-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
Bug Report
...ok, I lied a little:
- it is assignable if
Tis a type variable / generic; but - it is not assignable if
Tis concrete.
So this report can be seen either as the lack of support of an expected rule (when T is concrete), or an inconsistency between the rules for generics and the rules for concretes.
🔎 Search Terms
Searching for:
- "Partial"
- "Partial undefined"
I found these potentially related issues:
- Type guard cannot remove
undefinedfromPartial<T>[keyof T] | undefined#45257 (comment) - [3.5.1] Type 'NonNullable<Partial<Config>[T]>' is not assignable to type 'Config[T]' #31675
#45257 looks very similar. However, I think this report is a simpler case, and seems more directly related to the definition of Partial<> / optional properties (?), as something that adds | undefined to the type of a property access expression. It also looks to me like a fix for this report would fix #45257 naturally.
#31675 also looks related, but from the non-nullable perspective rather than the nullable one. The non-nullable inference rule also appears to be missing from both generic inference and concrete inference (e.g., NonNullable<Partial<T>[K]> is not assignable for T[K] for both generic T and concrete T), so at least there isn't an inconsistency there.
🕗 Version & Regression Information
This changed between versions 3.3.3 and 3.5.1.
In 3.3.3, Partial<T>[K] was assignable to T[K] | undefined for both generic T and concrete T.
From 3.5.1, assignability is still allowed for generic T, but not for any particular concrete T.
⏯ Playground Link
Playground link with relevant code
💻 Code
type Foo = {
x: number,
y: string,
};
/** Reads a key of any Partial<T> as an optional. */
function getValueGeneric<T, K extends keyof T>(o: Partial<T>, k: K): T[K] | undefined {
return o[k]; // Ok: Type 'Partial<T>[K]' is assignable to type 'T[K] | undefined'
}
/** Reads a key of a Partial<Foo> as an optional. */
function getValueConcrete<K extends keyof Foo>(o: Partial<Foo>, k: K): Foo[K] | undefined {
return o[k]; // Error: Type 'Partial<Foo>[K]' is not assignable to type 'Foo[K] | undefined'
}🙁 Actual behavior
Partial<T>[K]is assignable toT[K] | undefinedwhenTis a genericPartial<T>[K]is not assignable toT[K] | undefinedwhenTis concrete
🙂 Expected behavior
- Assignability of
Partial<T>[K]toT[K] | undefinedshould be consistent for both genericTand concreteT - Both should be allowed