Conditional types fail to distribute in properties of mapped types
See original GitHub issueTypeScript Version: 3.7.0-dev.20190928
Search Terms: conditional mapped property union
Code
type NullifyStrings<T> = T extends string ? null : T
type NullifyStringsInPropsWorking<T> = { [K in keyof T]: NullifyStrings<T[K]> }
type NullifyStringsInPropsBroken<T> = { [K in keyof T]: T[K] extends string ? null : T[K] }
type TestType = { a: number | string }
// { a: number | null }
type WorkingReplaceProps = NullifyStringsInPropsWorking<TestType>
// { a: string | number }
type BrokenReplaceProps = NullifyStringsInPropsBroken<TestType>
Expected behavior:
NullifyStringsInPropsWorking
and NullifyStringsInPropsBroken
should be functionally identical - expanding the NullifyStrings
type alias in NullifyStringsInPropsWorking
results in the same definition as NullifyStringsInPropsBroken
.
Actual behavior:
NullifyStringsInPropsWorking
and NullifyStringsInPropsBroken
have different behaviour - BrokenReplaceProps
has type { a: string | number }
instead of the expected { a: number | null }
.
Playground Link: Link
Related Issues:
#28339, but seems to be different.
#22945 mentions
Since type aliases are equivalent to writing the expansion inline […]
but that is not the case here.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:5
Top Results From Across the Web
Documentation - Conditional Types - TypeScript
Conditional types help describe the relation between the types of inputs and outputs.
Read more >Typescript conditional mapped types loses return type ...
I'm trying to wrap my head around conditional mapped types. If I have a type defined as: type StringyProps<T> = { [K in...
Read more >Conditional Types in TypeScript - Marius Schulz
If the relationship test in the conditional type checks a naked type parameter, the conditional type is called a distributive conditional type, ...
Read more >Conditional types in TypeScript - Artsy Engineering
Then calling .toUpperCase() on the result would be an error. Let's add basic types to this function so we can let TypeScript worry...
Read more >Advanced Types
Similar to union and intersection types, conditional types are not permitted to reference themselves recursively. For example the following is an error. Example ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I didn’t, actually! After reading that section of the handbook, I think I still wouldn’t have understood it - the section focuses on some nice working examples and doesn’t show any examples for when things go wrong. IMO these things would be nice to have in the handbook for better understanding:
extends infer
.Duplicate of #23022, #23046, and #32274.
Regarding:
the subtext is that this only applies when inlining a type alias instantiated with a type parameter.
Did you see this section of the handbook: distributive-conditional-types?
I don’t mean this in a snide way — lots of people have been tripped up on this and if they are reading the handbook and still getting confused then I think that is good to know.