Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DesktopDatePickerProps<Date> error Type 'Date' does not satisfy the constraint 'never' in version 7.1.0 #12640

Closed
andylacko opened this issue Apr 2, 2024 · 17 comments · Fixed by #13476
Assignees
Labels
component: pickers This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation

Comments

@andylacko
Copy link

andylacko commented Apr 2, 2024

Steps to reproduce

Link to live example: this doesn't need repro, it is bad implementation of typescript
Steps:

  1. DesktopDatePickerProps<Date>
  2. pickers.d.ts
image

Current behavior

doesn't accept Date or any type except never

Expected behavior

To accept javascript Date class as type

Context

typescript

Your environment

  System:
    OS: macOS 14.4.1
  Binaries:
    Node: 21.7.1 - ~/Library/Caches/fnm_multishells/1738_1711985104552/bin/node
    npm: 10.5.0 - ~/Library/Caches/fnm_multishells/1738_1711985104552/bin/npm
    pnpm: 8.15.0 - ~/node_modules/.bin/pnpm
  Browsers:
    Chrome: 123.0.6312.87
    Edge: Not Found
    Safari: 17.4.1
  npmPackages:
    react: 18.2.0 => 18.2.0 
    react-dom: 18.2.0 => 18.2.0 
    typescript: ^5.4.3 => 5.4.3 

Search keywords: Type 'Date' does not satisfy the constraint 'never'

@andylacko andylacko added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Apr 2, 2024
@LukasTy
Copy link
Member

LukasTy commented Apr 3, 2024

Hello @andylacko, I was unable to reproduce your issue.
Please provide a minimal reproduction example. A StackBlitz or a minimal repository would be best.
Thank you. 🙏

@LukasTy LukasTy added status: waiting for author Issue with insufficient information component: pickers This is the name of the generic UI component, not the React module! and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Apr 3, 2024
@CWThomson
Copy link

I'm also seeing the same issue. I simply took the Joy UI sample code for the date range picker (JoyUI Sample Code). I changed the date provider to be date-fns and used pro version (@mui/x-date-pickers-pro).

As I was trying to create a standalone component I removed the wrapper components for JoyV6MultiInputRangeField as this is done elsewhere.

I then removed the unused imports and the issue started appearing. By leaving the following unused import in the code, the issue goes away. If you remove it, the issue appears

import { AdapterDateFns } from '@mui/x-date-pickers-pro/AdapterDateFnsV3';

Sample code

@LukasTy
Copy link
Member

LukasTy commented Apr 4, 2024

I then removed the unused imports and the issue started appearing. By leaving the following unused import in the code, the issue goes away. If you remove it, the issue appears

@CWThomson Which adapter and where are you using in your application?
Importing an adapter anywhere in your application will augment the declared module with relevant interface entry and make TS happy with the provided Date type.

TL/DR: I don't see a problem here, everything seems to work as expected. 👌

Are you by any chance building a component library and there is no place where a LocalizationProvider with the appropriate dateAdapter is defined? 🤔

@CWThomson
Copy link

Thanks @LukasTy . I am building a component library and using tsup. Its in the build process this fails (Storybook works fine). Your explanation makes perfect sense. Storybook does initialize a LocalizationProvider with the AdapterDateFnsV3 adapter. As a component library, we leave the downstream app to be responsible for initializing the LocalizationProvider. Thanks for your help!

@LukasTy
Copy link
Member

LukasTy commented Apr 4, 2024

@CWThomson does your library only support Date (date-fns) only?
Otherwise, it would probably make sense to keep the generics on your side as well. 🤔
If you specifically need TS to work with specific types, without using an adapter, maybe you could just declare the specific module yourself? 🤔

declare module '@mui/x-date-pickers/models' {
interface PickerValidDateLookup {
'date-fns': Date;
}
}

@CWThomson
Copy link

Our component library is for internal use only so we've standardized on date-fns. Thanks for the tips, may be a better approach to main flexibility.

@guicara
Copy link

guicara commented Apr 4, 2024

I'm also seeing the same issue.

With MUI X v7 and date-fns

TS2344: Type Date does not satisfy the constraint never

Here is the code of my custom component, extending the default DatePicker:

export interface CustomDatePickerProps<
  TDate extends PickerValidDate,
  TEnableAccessibleFieldDOMStructure extends boolean = false,
> extends DatePickerProps<TDate, TEnableAccessibleFieldDOMStructure> {
  // custom properties here...
}
function CustomDatePicker<TDate extends PickerValidDate, TEnableAccessibleFieldDOMStructure extends boolean = false>(
  props: CustomDatePickerProps<TDate, TEnableAccessibleFieldDOMStructure>,
) {
  // simplified version of my code (in real life I use styled to customize the style of DatePicker)
  return <DatePicker {...props} />
}

Usage:

<CustomDatePicker<Date> // --> TS2344: Type Date does not satisfy the constraint never
  value={new Date()}
/>

Edit: declaring the specific module (cf. @LukasTy reply below) fix the issue. But I'm not sure to understand why. My React app is already using LocalizationProvider with the AdapterDateFns.

It was working well before with MUI X v6, without this fix.

@LukasTy
Copy link
Member

LukasTy commented Apr 5, 2024

@guicara I tried reproducing your problem, but wasn't able to trigger the mentioned error if AdapterDateFns or AdapterDateFnsV3 is imported anywhere in the app. 🤷
Could you provide a minimal reproduction case (a GH repo or StackBlitz demo) for us to explore?

A minor nitpick regarding your wrapped component types:
Are you building a component library?
Do you plan to have multiple date libraries/adapters used?
Do you plan to use Pickers with both the regular input as well as the accessible DOM structure?
If not, consider statically defining your wrapped component interface:

export interface CustomDatePickerProps extends DatePickerProps<Date, false> {
  // custom properties here...
}

It was working well before with MUI X v6, without this fix.

In v7 we have introduced more type safety, because prior to v7 you could use AdapterDayjs, but could have been passing Date props to your components, which would have caused issues. 🙈
We haven't flagged this change as a BC and haven't added a mention in the migration guide, but maybe we should have done (do) that?
cc @flaviendelangle

@flaviendelangle
Copy link
Member

flaviendelangle commented Apr 5, 2024

It was working well before with MUI X v6, without this fix.

In v6, the type of the date was inferred from the props;
This mean that TypeScript was able to complain for the following code:

// Invalid because `value` and `onChange` should have the same typing
<LocalizationProvider dateAdapter={AdapterDayjs]>
  <DatePicker value={new Date()} onChange={(date: Dayjs) => {}} />
</LocalizationProvider>

But it was not able to complain for the following code:

// `value` and `onChange` are coherent, but they are not compatible with `AdapterDayjs`
<LocalizationProvider dateAdapter={AdapterDayjs]>
  <DatePicker value={new Date()} onChange={(date: Date) => {}} />
</LocalizationProvider>

This was super problematic because people tend to pass Date objects when using adapters like AdapterDayjs and complain that it does not work.

Our solution was to limit the valid types for the date to the one supported by the adapter(s) you imported.


In your example, you are using AdapterDateFns, so the valid date is Date.

It seems that you are importing it outside of the typescript project used to check the file that throws an error.
Without more information it is hard to know why, this is probably related to how you application is structure and TS configured (and it can be configured that way for very good reasons).

You should be able to get rid of the error by adding the AdapterDateFns to the typescript project.
I see 3 solutions to do it depending on your setup and what you prefer:

  1. Add an import type {} from '@mui/x-date-pickers/AdapterDateFns' to a file at the root of your application (_app on Next.js for example)
  2. Add "./node_modules/@mui/x-date-pickers/AdapterDateFns/index.d.ts" to your tsconfig.json file (this only works if you did not exclude all the node_modules, which is the case on Next.js and maybe in other frameworks...).
  3. Create a file importAdapter.ts somewhere, add import type {} from '@mui/x-date-pickers/AdapterDateFns' to it add register it in tsconfig.json (it's a mix of 1. and 2. if you don't have a good file to put it in).

@LukasTy I do agree that a section in the migration guide would be a nice addition

@guicara
Copy link

guicara commented Apr 5, 2024

Thank you for your help and replies.

The issue was on my side due to a wird dependencies issues between the app consuming the design system and the design system itself.

Are you building a component library?

Yes

Do you plan to have multiple date libraries/adapters used?

Yes

Copy link

The issue has been inactive for 7 days and has been automatically closed.

@fcpauldiaz
Copy link

fcpauldiaz commented Apr 11, 2024

@guicara @andylacko I'm having the same issue, how did you fixed it?

@LukasTy LukasTy added docs Improvements or additions to the documentation and removed status: waiting for author Issue with insufficient information labels Apr 11, 2024
@LukasTy LukasTy reopened this Apr 11, 2024
@LukasTy
Copy link
Member

LukasTy commented Apr 11, 2024

I've moved the issue to our grooming board as we've agreed that adding a migration doc section about this would be beneficial.
@fcpauldiaz Have you read the whole discussion? I think that especially this comment: #12640 (comment) should answer most of your questions.
If you are still experiencing issues, could you provide a minimal reproduction example or at least describe your setup in more detail? 🤔

@fcpauldiaz
Copy link

The 3 solutions proposed didn't worked for me, but I was able to fix it by importing the adapter without using in next.js.

import { AdapterDateFns as _ } from "@mui/x-date-pickers/AdapterDateFnsV3";

@LukasTy
Copy link
Member

LukasTy commented Apr 15, 2024

The 3 solutions proposed didn't worked for me, but I was able to fix it by importing the adapter without using in next.js.

import { AdapterDateFns as _ } from "@mui/x-date-pickers/AdapterDateFnsV3";

@fcpauldiaz Which date-fns package version are you using?
If it is v3, then you should have tried

import type {} from '@mui/x-date-pickers/AdapterDateFnsV3';

Does that help?
Importing the whole adapter without explicitly using it seems a bit inefficient. 🤔

@fcpauldiaz
Copy link

this fixed the issue! thanks @LukasTy

Copy link

⚠️ This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@andylacko: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: pickers This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants