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

[pickers] AdapterDateFnsV3: Wrong types generated #13226

Closed
alexey-kozlenkov opened this issue May 23, 2024 · 13 comments · Fixed by #13464
Closed

[pickers] AdapterDateFnsV3: Wrong types generated #13226

alexey-kozlenkov opened this issue May 23, 2024 · 13 comments · Fixed by #13464
Assignees
Labels
bug 🐛 Something doesn't work component: pickers This is the name of the generic UI component, not the React module! typescript

Comments

@alexey-kozlenkov
Copy link
Contributor

alexey-kozlenkov commented May 23, 2024

Steps to reproduce

Link to live example: (https://codesandbox.io/p/sandbox/brave-matsumoto-9t8tqx?file=%2Fsrc%2FDemo.tsx%3A16%2C2)

Steps:

  1. Open sandbox
  2. Check produced TS type of const res in test function
  3. Or open AdapterDateFnsV3 file

Current behavior

Return types of AdapterDateFnsV3 functions are mostly any instead of their actual values
image

Expected behavior

Correspond to MuiPickersAdapter interface

Context

I'm trying to write an extended version of DateUtilsAdapterV3 with some custom utility functions and they reuse function if DateUtilsAdapterV3, which provides wrong typings.

Your environment

Executed in a devbox: https://codesandbox.io/p/devbox/y8p8k9?file=%2Fsrc%2FDemo.tsx%3A5%2C48

npx @mui/envinfo ``` Don't forget to mention which browser you used. System: OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm) Binaries: Node: 20.9.0 - /usr/local/bin/node npm: 9.8.1 - /usr/local/bin/npm pnpm: 8.10.2 - /usr/local/share/npm-global/bin/pnpm Browsers: Chrome: Not Found npmPackages: @emotion/react: latest => 11.11.4 @emotion/styled: latest => 11.11.5 @mui/material: next => 6.0.0-alpha.8 @mui/x-date-pickers: latest => 7.5.1 @types/react: latest => 18.3.2 react: latest => 18.3.1 react-dom: latest => 18.3.1 typescript: latest => 5.4.5 ```

Used browser: Version 125.0.6422.61 (Official Build) (arm64)

Search keywords: adapterdatefnsv3 date-fns date-fns-v3

@alexey-kozlenkov alexey-kozlenkov added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label May 23, 2024
@oliviertassinari oliviertassinari added component: pickers This is the name of the generic UI component, not the React module! labels May 23, 2024
@michelengelen michelengelen changed the title [AdapterDateFnsV3] Wrong types generated [pickers] AdapterDateFnsV3: Wrong types generated May 24, 2024
@michelengelen michelengelen added bug 🐛 Something doesn't work typescript and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels May 24, 2024
@michelengelen
Copy link
Member

Thanks @alexey-kozlenkov for opening this issue. 👍🏼
I did add this to the board for the team to estimate and fix.

@alexey-kozlenkov
Copy link
Contributor Author

@michelengelen I made a POC with a possible option to solve this, if team could have a look and decide if that's viable would be great

@LukasTy
Copy link
Member

LukasTy commented May 31, 2024

@alexey-kozlenkov Thank you for your contribution! 🙏
I'm not sure that your suggested approach is going to work, because that is a massive breaking change and request from users to install the date-fns v3 aliased in their applications. If they don't do it, the result is:
Screenshot 2024-05-31 at 17 01 35

We'll have to look for an alternative solution. 👍

@alexey-kozlenkov
Copy link
Contributor Author

alexey-kozlenkov commented May 31, 2024

Ah, I see, thanks @LukasTy.
I'll close that PR

@LukasTy
Copy link
Member

LukasTy commented Jun 11, 2024

We've decided to try an approach of adding explicit function returns in hopes of fixing this problem in the built packages.
This would need to be done for both regular and V3 adapters as changing the date-fns version would move the problem to the AdapterDateFns.

An example of the idea:

- public isSameYear = (value: Date, comparing: Date) => {
+ public isSameYear = (value: Date, comparing: Date): boolean => {

@alexey-kozlenkov would you be interested in taking care of this problem with the suggested approach? 🤔

@alexey-kozlenkov
Copy link
Contributor Author

@LukasTy yeah, sure

@eglavin
Copy link

eglavin commented Jun 13, 2024

Would this be why I'm unable to assign anything to a date picker? I'm getting this error when the type is Date | null:
image

Or would I be experiencing a different issue?

Relevant dependencies:

"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.5",
"@mui/icons-material": "5.15.20",
"@mui/material": "5.15.20",
"@mui/x-date-pickers": "7.6.0",
"date-fns": "3.6.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",

Typescript error:

Type 'Date | null' is not assignable to type 'null | undefined'.
  Type 'Date' is not assignable to type 'null | undefined'.ts(2322)
usePickerValue.types.d.ts(179, 5): The expected type comes from property 'value' which is declared here on type 'IntrinsicAttributes & DesktopDateTimePickerProps<never, false> & RefAttributes<HTMLDivElement>'

Weirdly not running into this issue on a code sandbox though:
https://codesandbox.io/p/devbox/x8lcsv?file=%2Fsrc%2FDemo.tsx%3A11%2C55

@LukasTy
Copy link
Member

LukasTy commented Jun 13, 2024

@eglavin do you have a AdapterDateFnsV3 import somewhere in your application? 🤔
And is your fromDate really typed correctly (Date | null) in your application?

@eglavin
Copy link

eglavin commented Jun 13, 2024

Ahh ok yeah importing it directly in the project its self seems to make it work correctly. kinda breaks what we're doing though.

Essentially we have a micro-frontend stack which means our theme config is in a separate library which contains our theme providers like so:

import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
import { StyledEngineProvider, ThemeProvider as MuiThemeProvider } from "@mui/material/styles";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3";

...

export const ThemeProvider = ({ children }: { children: React.ReactNode }): JSX.Element => {
	const [activeTheme, setActiveTheme] = useState<Theme>("dark");
	const selectedTheme = useMemo(() => generateTheme(activeTheme), [activeTheme]);

	const snackbarRef = useRef<SnackbarProvider | null>(null);

	return (
		<ThemeContext.Provider value={{ activeTheme, setActiveTheme }}>
			<StyledEngineProvider injectFirst>
				<MuiThemeProvider theme={selectedTheme}>
					<EmotionThemeProvider theme={selectedTheme}>
						<LocalizationProvider dateAdapter={AdapterDateFns}>
							<SnackbarProvider
								ref={snackbarRef}
								maxSnack={3}
								preventDuplicate
								anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
								action={(key) => <SnackbarAction id={key} snackbarRef={snackbarRef.current} />}
							>
								{children}
							</SnackbarProvider>
						</LocalizationProvider>
					</EmotionThemeProvider>
				</MuiThemeProvider>
			</StyledEngineProvider>
		</ThemeContext.Provider>
	);
};

This ThemeProvider component is then bundled in an internal npm package which gets installed onto each micro-frontend, how does typescript then know which adapter is being used? is there a mechanism to tell typescript which adapter is being used without importing it into every frontend app?

@eglavin
Copy link

eglavin commented Jun 13, 2024

Ok I see it, you have this interface declared in the adapter function. I'll be able to use this to get it to register, thanks for you're help @LukasTy!

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

@LukasTy
Copy link
Member

LukasTy commented Jun 13, 2024

Are all your frontend apps using AdapterDateFns?
In which case feel free to follow suggestions in #12640 (comment) or later messages.
import type {} from '@mui/x-date-pickers/AdapterDateFnsV3' is slightly more fool proof, but declaring your own module as you mentioned is also a viable choice. 👍

@eglavin
Copy link

eglavin commented Jun 13, 2024

Most if not all do yes, this will work for now, thanks again! 😁

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.

@alexey-kozlenkov: 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
bug 🐛 Something doesn't work component: pickers This is the name of the generic UI component, not the React module! typescript
Projects
None yet
5 participants