You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
keyof NonNullable<T> cannot be used to index type T #23368
Partial dupe of #22934 ? In any case, also should also be "fixed" by #22971
The root cause is still that NonNullable<T> and T are (rightly) unrelated in this direction, but when T extends object, one expects NonNullable<T> to just beT.
Hey everyone. I was trying to figure this issue out and I realized that keyof <Higher order type> reduces to string | number | symbol which is causing this problem.
If this issue is worth fixing, I suggest adding the following rule to the isTypeRelated relation.
keyof X extends keyof Y
when
Y extends X
This rule should be applied before the rule that reduces keyof Y to string | number | symbol because that loses the type relationship between X and Y
Example of the first rule being applied:
function f<X, Y extends X>(keyofX: keyof X, keyofY: keyof Y) {
keyofY = keyofX; // fine because keyof X is a subset of keyof Y
keyofX = keyofY; // error because Y may have more keys than X
}
Right now, an error is raised, but for the wrong reasons.
It tries to assign string | number | symbol to keyofX after reducing keyof Y which is fine, but would miss out on edge cases like this.
The original issue doesn't occur anymore but this does
functionf1<T>(keyofT: keyofT,keyofNonNullT: keyofNonNullable<T>){keyofT=keyofNonNullT// should not raise error but does on the latest master}
EDIT:
Okay, I implemented the new rule but turns out this isn't quite enough to fix the second example because NonNullable<T> extends T is false. I think this would require another rule for conditional types.
I implemented a special case for checks like
(keyof isRelatedTo keyof ( extends ? ... : ...))
right before the checker gives up and reduces the source type to string | number | symbol which works as expected.
Is that kind of logic too much of a special case for the type checker? NonNullable has become kinda pervasive so I don't know.
Activity
weswigham commentedon Apr 12, 2018
Partial dupe of #22934 ? In any case, also should also be "fixed" by #22971
The root cause is still that
NonNullable<T>andTare (rightly) unrelated in this direction, but whenT extends object, one expectsNonNullable<T>to just beT.weswigham commentedon Apr 12, 2018
Andy (Andrewkraft) (@Andy-MS) I think that's just because narrowing doesn't apply higher order types right now.
dhruvrajvanshi commentedon Apr 30, 2019
Hey everyone. I was trying to figure this issue out and I realized that
keyof <Higher order type>reduces tostring | number | symbolwhich is causing this problem.If this issue is worth fixing, I suggest adding the following rule to the
isTypeRelatedrelation.This rule should be applied before the rule that reduces
keyof Ytostring | number | symbolbecause that loses the type relationship between X and YExample of the first rule being applied:
Right now, an error is raised, but for the wrong reasons.
It tries to assign
string | number | symbolto keyofX after reducingkeyof Ywhich is fine, but would miss out on edge cases like this.The original issue doesn't occur anymore but this does
EDIT:
Okay, I implemented the new rule but turns out this isn't quite enough to fix the second example because
NonNullable<T> extends Tis false. I think this would require another rule for conditional types.dhruvrajvanshi commentedon Apr 30, 2019
Update:
I implemented a special case for checks like
(keyof
isRelatedTokeyof ( extends ? ... : ...))right before the checker gives up and reduces the source type to
string | number | symbolwhich works as expected.Is that kind of logic too much of a special case for the type checker?
NonNullablehas become kinda pervasive so I don't know.