Improve generic keyof relationship checking for generic conditionals with keyless branch types#49563
Improve generic keyof relationship checking for generic conditionals with keyless branch types#49563weswigham wants to merge 1 commit intomicrosoft:mainfrom
Conversation
…with keyless branch types
|
Can you give an example of how a particular react libraries would benefit from this? A concrete example of usage would help me understand how widely applicable it might be. |
|
Hmm, I'm not sure these changes are desirable. See the discussion here. We effectively rely on the fact that |
|
I dunno, all the cases in the test in this PR seem pretty desirable... |
|
(also that's unchanged by this PR?) |
|
With this PR there is no error in the example below where previously there was. The error is desirable because it protects us from accessing through a possibly-null object without requiring local proof that the object is non-null. The thing that saves us is that type NonNull<T> = T extends null ? never : T;
function foo<T>(t: T, k: keyof NonNull<T>) {
t[k]; // Was error, now isn't
}
foo(null, 'foo'); |
|
If that should be invalid, it should be because |
I'm quite certain that would be a severe breaking change, and it would force checks that are unnecessary because we're already protecting you by having |
Except it's not Point being we can clearly do better here. Using one problem to excuse another isn't a great place to be - both probably need fixing. |
|
@weswigham do you want to keep working on this? Is there a reasonable path to fixing the |
|
It's been almost 3 years since the last change to this PR. I'm going to close it for now and we can re-open it if it's worth working on before the Strada code is decommissioned. |
Originally from #49091. This essentially applies
keyofto the constraint of a conditional in a deferred way, ignoring branches which don't contribute to the final result set of keys. This allows, eg,keyof (T extends null ? never : T)to be related tokeyof T. In addition, intersection members for whomkeyofreturnsneverare omitted from the relationship check, allowing a deferred effectivekeyof (T & object)to be related tokeyof T(which already works when not indirected via a conditional via construction).So in total, given a type like
then
keyof FilterNull<(T & object) | null>is now able to be related tokeyof T.Practically, I initially looked into this to support using the conditional-based
NonNullablein more places, but now that it's just an intersection, this is moreso just for users usingkeyofover their own filtering conditionals (as is common inreactlibraries nowadays).