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
Immediate keyof operation on intersection of generic mapped types incorrectly results in never type #22291
Search Terms:
keyof, intersection, mapped type, generic, type parameter, never
Code
typeExample1<Textendsstring,Uextendsstring>=keyof(Record<T,any>&Record<U,any>)typeResult1=Example1<'x','y'>// Type of Result1 is never but it should be 'x' | 'y'/** The additional examples below are just for context */typeResult2=keyof(Record<'x',any>&Record<'y',any>)// Type of Result2 is 'x' | 'y' as expectedtypeExample3<Textendsstring>=keyof(Record<T,any>)typeResult3=Example3<'x'|'y'>// Type of Result3 is 'x' | 'y' as expectedtypeExample4<Textendsstring,Uextendsstring>=(Record<T,any>&Record<U,any>)typeResult4=keyofExample4<'x','y'>// Type of Result4 is 'x' | 'y' as expectedtypeExample5<T,U>=keyof(T&U)typeResult5=Example5<Record<'x',any>,Record<'y',any>>// Type of Result5 is 'x' | 'y' as expected
Expected behavior: Result1 should have a type of 'x' | 'y'
The issue here is that for generic types A and B we should consider keyof (A & B) to be equivalent to keyof A | keyof B. We currently don't implement that transformation. If we did, we would transform keyof (Record<T, any> & Record<U, any>) to keyof Record<T, any> | keyof Record<U, any>, which we already reduce to T | U, the desired result.
Activity
ahejlsberg commentedon Mar 2, 2018
The issue here is that for generic types
AandBwe should considerkeyof (A & B)to be equivalent tokeyof A | keyof B. We currently don't implement that transformation. If we did, we would transformkeyof (Record<T, any> & Record<U, any>)tokeyof Record<T, any> | keyof Record<U, any>, which we already reduce toT | U, the desired result.