Description
Bug Report
...ok, I lied a little:
- it is assignable if
T
is a type variable / generic; but - it is not assignable if
T
is 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
undefined
fromPartial<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] | undefined
whenT
is a genericPartial<T>[K]
is not assignable toT[K] | undefined
whenT
is concrete
🙂 Expected behavior
- Assignability of
Partial<T>[K]
toT[K] | undefined
should be consistent for both genericT
and concreteT
- Both should be allowed