NonNullable isn't narrowing down object values' types for optional properties
See original GitHub issueTypeScript Version: 3.2.0-dev.20181106
Search Terms: NonNullable object NonNullable object values
Code
Run the following code via tsc --no-emit --strict test.ts
:
interface P {
color?: 'red' | 'green';
}
type RequiredP = {
[K in keyof P]: NonNullable<P[K]>;
}
declare const p: RequiredP;
const color: 'red' | 'green' = p.color;
Expected behavior:
The resulting type should not allow undefined
for the value at a property color
.
Actual behavior:
undefined
is still allowed. Using the NonNullable
type doesn’t seem to have any effect.
Playground Link: Note: you need to enable strictNullChecks
manually!
https://www.typescriptlang.org/play/#src=interface P {
color%3F%3A ‘red’ | ‘green’%3B
}
type RequiredP %3D {
[K in keyof P]%3A NonNullable<P[K]>%3B
}
declare const p%3A RequiredP%3B
const color%3A ‘red’ | ‘green’ %3D p.color%3B
Related Issues:
Issue Analytics
- State:
- Created 5 years ago
- Reactions:8
- Comments:9 (1 by maintainers)
Top Results From Across the Web
Type an object with optional keys, but non-null value for keys ...
With --strictNullChecks turned on, the signature {[k: string]: SomeType} is saying that every single string-key property exists and is of type ...
Read more >Documentation - Narrowing - TypeScript
The “true” branch narrows x 's types which have either an optional or required property value , and the “false” branch narrows to...
Read more >Type-Safe TypeScript with Type Narrowing - Rainer Hahnekamp
Date is the type of input and not its value. ... Strictly speaking function is not a real type, it is a callable...
Read more >When to use `never` and `unknown` in TypeScript
Types explained using set theory. When you get down to a fundamental definition a type is a set of possible values, and nothing...
Read more >narrowing types via type guards and assertion functions - 2ality
Note that narrowing does not change the original type of value , it only ... @ts-ignore: Property 'name' does not exist on type...
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 Free
Top 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
Here is the generic version:
@mgol Let me know if I misunderstood the problem, but I think this issue is just about the fact that your
RequiredP
is a homomorphic mapped type. This means that the optionality of the field is preserved inRequiredP
If you use-?
(added by this PR) you can remove the optional modifier explicitly and all will work as expected as far as I can tell:play
Note: Mapped types are only homomorphic if they map over
keyof T
whereT
is any type or if they map overK
whereK
is a type parameter extendingkeyof T
. This is why your workarounds worked because they broke the pattern for homomorphic mapped types.