-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Extending mapped type doesn't allow extra properties when extended type has string literal values #27707
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
Comments
Possibly related: #27421 |
How does Note that from the type system's perspective, |
The original problem is in react-native's typings (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-native/index.d.ts#L5222) which uses the first form and has some weird behavior related to inference. I had a hard time describing the problem, so I tried to narrow it down a bit. The working variants were a result of messing around to try to isolate the issue. |
@asmundg I think it might actually be a type definition issue. Update updating - type NamedStyles<T> = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };
+ type NamedStyles = { [key: string]: ViewStyle | TextStyle | ImageStyle }; The issue seems to be resolved locally |
As you point out in the DefinitelyTyped PR, extending It seems like the pattern the code aims for is "for each property in an object, the value type must extend V", which seems difficult do do without referring to T or requiring an index signature. Or requiring T to be explicitly provided instead of letting it be inferred. |
I'm closing this issue since the underlying issue is By Design for Typescript itself, and a PR for a fix of |
TypeScript Version: 3.2.0-dev.20181011
Search Terms: extends mapped literal widening
Code
Expected behavior:
Code compiles for all cases.
Actual behavior:
Code fails when extending a mapped type with string literal properties:
Removing either the mapping, the string literal or the widenable input makes the code pass type checking.
Also notable is that the
one.a
property of the function argument is only inferred to be defined by the extended type in the first case. E.g. jumping to definition only does something in the first f() call.This seems related to the
a
property being widened when mapped over.Playground Link: http://www.typescriptlang.org/play/#src=%2F%2F%20Type%20'%7B%20a%3A%20string%3B%20c%3A%20number%3B%20%7D'%20is%20not%20assignable%20to%20type%20'%7B%20a%3A%20%22a%22%3B%20%7D'.%0D%0A%2F%2F%20%20%20Object%20literal%20may%20only%20specify%20known%20properties%2C%20and%20'c'%20does%20not%20exist%20in%20type%20'%7B%20a%3A%20%22a%22%3B%20%7D'.%20%5B2322%5D%0D%0Aconst%20f%3A%20%3CT%20extends%20%7B%20%5BP%20in%20keyof%20T%5D%3A%20%7B%20a%3A%20%22a%22%20%7D%20%7D%3E(literal%3A%20T)%20%3D%3E%20void%20%3D%20()%20%3D%3E%20%7B%7D%0D%0Af(%7Bone%3A%20%7Ba%3A%20%22a%22%2C%20c%3A%201%7D%7D)%0D%0A%0D%0A%2F%2F%20works%0D%0Aconst%20a%3A%20%22a%22%20%3D%20%22a%22%0D%0Af(%7Bone%3A%20%7Ba%3A%20a%2C%20c%3A%201%7D%7D)%0D%0A%0D%0A%2F%2F%20works%0D%0Aconst%20f_%3A%20%3CT%20extends%20%7B%20%5BP%20in%20keyof%20T%5D%3A%20%7B%20a%3A%20string%20%7D%20%7D%3E(literal%3A%20T)%20%3D%3E%20void%20%3D%20()%20%3D%3E%20%7B%7D%0D%0Af_(%7Bone%3A%20%7Ba%3A%20%22a%22%2C%20c%3A%201%7D%7D)%0D%0A%0D%0A%2F%2F%20works%0D%0Aconst%20f__%3A%20%3CT%20extends%20%7Bone%3A%20%7B%20a%3A%20%22a%22%20%7D%7D%3E(literal%3A%20T)%20%3D%3E%20void%20%3D%20()%20%3D%3E%20%7B%7D%0D%0Af__(%7Bone%3A%20%7Ba%3A%20%22a%22%2C%20c%3A%201%7D%7D)%0D%0A
Related Issues:
The text was updated successfully, but these errors were encountered: