Closed
Description
TypeScript Version: 3.5.0-dev.20190417
Search Terms:
generics, resolved, nested generics, specified, assignable, type safety, type alias, compatible
Code
interface A { a: number; }
interface B { b: string; }
type Demo<T> = <K extends keyof T> (key: K, val: T[K]) => void
// Demo<A> should not be assignable to Demo<B>, but it is?!
declare const implDemoA: Demo<A>;
const implDemoB: Demo<B> = implDemoA; // no error!? 😕
Expected behavior:
There should be an error that a type Demo<A>
is not assignable to Demo<B>
.
Actual behavior:
It compiles with no error.
I guess the compiler "forgets" what concrete type T
is, since it doesn't appear directly in the resulting type. If one manually substitutes A
and B
for T
into the definition of Demo<T>
to make DemoA
and DemoB
, everything behaves as expected:
// Note that we can manually make a concrete type DemoA and DemoB:
type DemoA = <K extends keyof A>(key: K, val: A[K]) => void;
type DemoB = <K extends keyof B>(key: K, val: B[K]) => void;
type MutuallyAssignable<T extends U, U extends V, V = T> = true;
// the compiler agrees that DemoA and Demo<A> are mutually assignable
declare const testAWitness: MutuallyAssignable<Demo<A>, DemoA>; // okay
// the compiler agrees that DemoB and Demo<B> are mutually assignable
declare const testBWitness: MutuallyAssignable<Demo<B>, DemoB>; // okay
// And the compiler *correctly* sees that DemoA is not assignable to DemoB
declare const implDemoAConcrete: DemoA;
const implDemoBConcrete: DemoB = implDemoAConcrete; // error as expected
// ~~~~~~~~~~~~~~~~~ <-- Type 'DemoA' is not assignable to type 'DemoB'.
This comes from a question on Stack Overflow.
Playground Link:
👩💻🔗
Related Issues:
I'm not finding anything I am confident is related: 🔍👀∅⁉