Types: allow undefined in ClassNames values (classNames breaks under exactOptionalPropertyTypes)
- Dominant language
- TypeScript
- Stars
- 6.9k
- Forks
- 780
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 3
Description
### Summary
`ClassNames` types every slot as a required `string`, so the `classNames` prop (`classNames?: Partial`) becomes `{ [key]?: string }`. Under `exactOptionalPropertyTypes: true`, a value of type `string | undefined` — which is what most class-name builders return (`clsx`, `cva`, `tailwind-variants`, and similar) — is **not** assignable to an optional-`string` property, so `classNames` fails to type-check with `TS2375`.
The sibling `Styles` type already allows `undefined` in its values; `ClassNames` does not. Aligning the two would fix the incompatibility and remove the inconsistency.
### Version
- `@daypicker/react` `10.0.1` (core `react-day-picker` `10.0.1`)
- TypeScript with `"exactOptionalPropertyTypes": true`
### Current types
```ts
// react-day-picker/dist/esm/types/shared.d.ts
export type ClassNames = {
[key in UI | SelectionState | DayFlag | Animation]: string;
};
export type Styles = {
[key in UI | SelectionState | DayFlag]: CSSProperties | undefined; // ← already allows undefined
};
// react-day-picker/dist/esm/types/props.d.ts
classNames?: Partial;
```
### Reproduction
```tsx
// tsconfig.json → "compilerOptions": { "exactOptionalPropertyTypes": true }
import { DayPicker } from "@daypicker/react";
// what clsx()/cva()/tailwind-variants and similar helpers return:
const maybeClass: string | undefined = Math.random() > 0.5 ? "text-red-500" : undefined;
export function Example() {
return ;
// TS2375: Type '{ root: string | undefined }' is not assignable to type
// 'Partial' with 'exactOptionalPropertyTypes: true'.
}
```
Without `exactOptionalPropertyTypes`, `?: string` widens to `string | undefined`, so this compiles. With it enabled, an optional `?: string` means "absent **or** a string, never an explicit `undefined`", so a `string | undefined` value is rejected.
### Proposed change
Allow `undefined` in the `ClassNames` values, mirroring `Styles`:
```ts
export type ClassNames = {
[key in UI | SelectionState | DayFlag | Animation]: string | undefined;
};
```
This is a types-only change (no runtime impact) and makes `classNames` work under `exactOptionalPropertyTypes` and with the `string | undefined` values that class-name utilities commonly produce.
Contributor guide
Research direction
Start with react-day-picker/dist/esm/types/shared.d.ts and compare ClassNames with Styles; props.d.ts shows how ClassNames is used by classNames. Reproduce the error using the tsconfig exactOptionalPropertyTypes setting and the Example component, then confirm the example type-checks while the change remains types-only with no runtime impact.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100