-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Better support for 'defaultProps' in JSX #23812
Comments
No. We're better than this now. Instead, for your consideration: namespace JSX {
export type LibraryManagedProps<TComponent, TProps> = /*...*/
} which can be defined as: namespace JSX {
export type LibraryManagedProps<TComponent, TProps> =
TComponent extends { defaultProps: infer D; propTypes: infer P; } ? Defaultize<TProps & InferedPropTypes<P>, D>
: TComponent extends { defaultProps: infer D } ? Defaultize<TProps, D>
: TComponent extends { propTypes: infer P } ? TProps & InferedPropTypes<P>
: TProps;
} where We shouldn't tie functionality to strings or properties anymore - we don't need to (we have generic index types now - the property references were a hack for before we had them). And "Defaultize is ugly" isn't really a great argument against it, because that exact type would need to be hardcoded into the checker to make the property-name thing work (except even uglier because it'd have no alias, so would be represented in declaration emit and quick info with no aliasing and a ton of nested conditionals), except it wouldn't be able to be recoded if/when the JSX library's functionality changes - it would hardcode the compiler to the current version and implementation of react (specifically), which should be an nongoal. |
How are |
One thing I'd like to mention is that it doesn't support generic components yet, which has nothing to do with So if your component has UPDATE: One of error messages
|
defaultProps don't work with HOCs =\ HOCs
Component with
Using
However I indicated |
@inomdzhon You did not actually declare Although it's probably worth mentioning that even if you alter your component to get that right, you may need to be on nightly for it to work, since we partially fixed a related issue in intersected types a few days ago. |
@weswigham any chance for a code example of how that could work? :) I've been playing around with it, I have an example here: https://gist.github.com/madou/0de18176fc30c26767e2705f0f5281ef Running into a problem of |
@Madou woh, it's work 😲...unless this error 🤔 |
@Madou I've encountered the same issue - "solved" it by casting the passed component back to a React.ComponentType. You can see it in action here: withForm.tsx It works, but it really feels more like an ugly workaround. I'd appreciate it if someone would find a nicer solution! |
@weswigham hi) what you think about @maschino solution for "provide" defaultProps to HOC? |
This proposal aims to fix problems around React's use of
defaultProps
, which TypeScript has trouble understanding today.Background
Today, React has a concept called
defaultProps
; these are props that an external user of a component may consider optional, but are always present in the component definition.Unfortunately, TypeScript
--strictNullChecks
users who want to take advantage of this are in a tough spot.They can either specify these props as optional and assert that defaulted properties are present internally,
or they can jump through levels of indirection:
Proposals
Using resolution semantics of the JSX factory
Users can already emulate this behavior with
React.createElement
: https://tinyurl.com/y9jbptt9In theory, just passing the right data to the JSX factory should do the work for us.
However, there are some issues:
Defaultize
type is hard to read.createElement
as an inference site, and when inference fails, users get no completions for props. It's not ideal in the general case, but the goal is to continue to give a good experience in JSX.Add a new type in the JSX namespace
We could potentially add a new field called
ComponentDefaultPropNames
inJSX
which would either be a union of literal types or possibly an object type whose property names describe the respective names thatdefaultProps
could have:When writing out a JSX tag for a component,
JSX.ComponentDefaultPropNames
is looked up on the type of the tag name to determine which properties should be considered optional.So for example:
If
TagName
expects props with the typeProps
, TypeScript can relatetypeof someObject
to some combination ofProps
and(typeof TagName)[JSX.ComponentDefaultPropNames]
.Potential issues
Under either proposal, some type is inferred from the type of the component's
defaultProps
property.Since React's
.d.ts
files currently definedefaultProps
to be aPartial<P>
, whereP
is the type parameter for the type of props, we need to avoid that from making all props optional.To avoid issues here, we could say that only required properties on
defaultProps
satisfy a JSX element's type. So for example:The text was updated successfully, but these errors were encountered: