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
typeFoo<K,T>=KextendskeyofT ? T[K] : never;functiontest1<K,T>(foo: Foo<K,T>){}functiontest2<KextendskeyofT,T>(foo: T[K]){test1(foo);// ^ Argument of type 'T[K]' is not assignable to parameter of type 'Foo<K, T>'}
π Actual behavior
We get an error message:
Argument of type 'T[K]' is not assignable to parameter of type 'Foo<K, T>'
π Expected behavior
No error.
Additional information about the issue
I have tried asking this as a question on StackOverflow, but haven't received an answer that resolves whether this is an expected behavior or a current limitation of the compiler narrowing capabilities.
The problem came up during the rather complex typing for adding generics to the EventEmitter class.
interfaceT{myEvent: [string]}// It's now possible to have a specialized event emitter:constemitter: EventEmitter<T>=newEventEmitter();// We expect to be able to type the listener a straight-forward way:typeListener<KextendskeyofT>=(...args: T[K])=>void;functionon<KextendskeyofT>(event: K,listener: Listener<K>): void{// This won't work because `on` is typed using conditional typing:emitter.on(event,listener);}
The code example presented in this issue is a distillation of this issue where knowing that K extends keyof T is not enough to narrow a conditional type with the exact same condition.
Finally, if you're wondering why the typing of EventEmitter uses conditional typing in this way, the answer is because it has to support the default case with all the bells and whistles (i.e. how it's been used in existing code).
The text was updated successfully, but these errors were encountered:
The error in your emitter example is correct, because K can be a union type, so event and listener can have incompatible types. Same issue as #57691 and many many others.
The first error is most likely simply due to the deferred resolving of conditional types when they involve an unbound generic type. The compiler has no idea what the types K or T are, so it can't know what type Foo<K, T> resolves to. A known design limitation.
π Search Terms
"extends narrowing", "existential types"
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play?#code/C4TwDgpgBAYg9nAPAaQDRQCoD4oF4rJQQAewEAdgCYDOUA1hCHAGaZQD8mA2sgLpQAuKOQgA3CACcA3ACgZzAK7kAxsACWcclDLVgARhTpsACmYIh8JGkxYAlFADeUAL5zFK9Zu0RdAJhREpBQ09IwsmEZYpubcfPYOMlBJ3rp60XC2sq5AA
π» Code
π Actual behavior
We get an error message:
π Expected behavior
No error.
Additional information about the issue
I have tried asking this as a question on StackOverflow, but haven't received an answer that resolves whether this is an expected behavior or a current limitation of the compiler narrowing capabilities.
The problem came up during the rather complex typing for adding generics to the
EventEmitter
class.The code example presented in this issue is a distillation of this issue where knowing that
K extends keyof T
is not enough to narrow a conditional type with the exact same condition.The following typing fixes the error:
Finally, if you're wondering why the typing of
EventEmitter
uses conditional typing in this way, the answer is because it has to support the default case with all the bells and whistles (i.e. how it's been used in existing code).The text was updated successfully, but these errors were encountered: