=== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance5.ts === // checking subtype relations for function types as it relates to contextual signature instantiation // same as subtypingWithCallSignatures2 just with an extra level of indirection in the inheritance chain class Base { foo: string; } >Base : Base >foo : string class Derived extends Base { bar: string; } >Derived : Derived >Base : Base >bar : string class Derived2 extends Derived { baz: string; } >Derived2 : Derived2 >Derived : Derived >baz : string class OtherDerived extends Base { bing: string; } >OtherDerived : OtherDerived >Base : Base >bing : string interface A { // T >A : A // M's a: (x: number) => number[]; >a : (x: number) => number[] >x : number a2: (x: number) => string[]; >a2 : (x: number) => string[] >x : number a3: (x: number) => void; >a3 : (x: number) => void >x : number a4: (x: string, y: number) => string; >a4 : (x: string, y: number) => string >x : string >y : number a5: (x: (arg: string) => number) => string; >a5 : (x: (arg: string) => number) => string >x : (arg: string) => number >arg : string a6: (x: (arg: Base) => Derived) => Base; >a6 : (x: (arg: Base) => Derived) => Base >x : (arg: Base) => Derived >arg : Base >Base : Base >Derived : Derived >Base : Base a7: (x: (arg: Base) => Derived) => (r: Base) => Derived; >a7 : (x: (arg: Base) => Derived) => (r: Base) => Derived >x : (arg: Base) => Derived >arg : Base >Base : Base >Derived : Derived >r : Base >Base : Base >Derived : Derived a8: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; >a8 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >x : (arg: Base) => Derived >arg : Base >Base : Base >Derived : Derived >y : (arg2: Base) => Derived >arg2 : Base >Base : Base >Derived : Derived >r : Base >Base : Base >Derived : Derived a9: (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived; >a9 : (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived >x : (arg: Base) => Derived >arg : Base >Base : Base >Derived : Derived >y : (arg2: Base) => Derived >arg2 : Base >Base : Base >Derived : Derived >r : Base >Base : Base >Derived : Derived a10: (...x: Derived[]) => Derived; >a10 : (...x: Derived[]) => Derived >x : Derived[] >Derived : Derived >Derived : Derived a11: (x: { foo: string }, y: { foo: string; bar: string }) => Base; >a11 : (x: { foo: string; }, y: { foo: string; bar: string; }) => Base >x : { foo: string; } >foo : string >y : { foo: string; bar: string; } >foo : string >bar : string >Base : Base a12: (x: Array, y: Array) => Array; >a12 : (x: Base[], y: Derived2[]) => Derived[] >x : Base[] >Array : T[] >Base : Base >y : Derived2[] >Array : T[] >Derived2 : Derived2 >Array : T[] >Derived : Derived a13: (x: Array, y: Array) => Array; >a13 : (x: Base[], y: Derived[]) => Derived[] >x : Base[] >Array : T[] >Base : Base >y : Derived[] >Array : T[] >Derived : Derived >Array : T[] >Derived : Derived a14: (x: { a: string; b: number }) => Object; >a14 : (x: { a: string; b: number; }) => Object >x : { a: string; b: number; } >a : string >b : number >Object : Object } interface B extends A { >B : B >A : A a: (x: T) => T[]; >a : (x: T) => T[] >T : T >x : T >T : T >T : T } // S's interface I extends B { >I : I >B : B // N's a: (x: T) => T[]; // ok, instantiation of N is a subtype of M, T is number >a : (x: T) => T[] >T : T >x : T >T : T >T : T a2: (x: T) => string[]; // ok >a2 : (x: T) => string[] >T : T >x : T >T : T a3: (x: T) => T; // ok since Base returns void >a3 : (x: T) => T >T : T >x : T >T : T >T : T a4: (x: T, y: U) => T; // ok, instantiation of N is a subtype of M, T is string, U is number >a4 : (x: T, y: U) => T >T : T >U : U >x : T >T : T >y : U >U : U >T : T a5: (x: (arg: T) => U) => T; // ok, U is in a parameter position so inferences can be made >a5 : (x: (arg: T) => U) => T >T : T >U : U >x : (arg: T) => U >arg : T >T : T >U : U >T : T a6: (x: (arg: T) => U) => T; // ok, same as a5 but with object type hierarchy >a6 : (x: (arg: T) => U) => T >T : T >Base : Base >U : U >Derived : Derived >x : (arg: T) => U >arg : T >T : T >U : U >T : T a7: (x: (arg: T) => U) => (r: T) => U; // ok >a7 : (x: (arg: T) => U) => (r: T) => U >T : T >Base : Base >U : U >Derived : Derived >x : (arg: T) => U >arg : T >T : T >U : U >r : T >T : T >U : U a8: (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U; // ok >a8 : (x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U >T : T >Base : Base >U : U >Derived : Derived >x : (arg: T) => U >arg : T >T : T >U : U >y : (arg2: T) => U >arg2 : T >T : T >U : U >r : T >T : T >U : U a9: (x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U; // ok, same as a8 with compatible object literal >a9 : (x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U >T : T >Base : Base >U : U >Derived : Derived >x : (arg: T) => U >arg : T >T : T >U : U >y : (arg2: { foo: string; bing: number; }) => U >arg2 : { foo: string; bing: number; } >foo : string >bing : number >U : U >r : T >T : T >U : U a10: (...x: T[]) => T; // ok >a10 : (...x: T[]) => T >T : T >Derived : Derived >x : T[] >T : T >T : T a11: (x: T, y: T) => T; // ok >a11 : (x: T, y: T) => T >T : T >Base : Base >x : T >T : T >y : T >T : T >T : T a12: >(x: Array, y: T) => Array; // ok, less specific parameter type >a12 : (x: Base[], y: T) => Derived[] >T : T >Array : T[] >Base : Base >x : Base[] >Array : T[] >Base : Base >y : T >T : T >Array : T[] >Derived : Derived a13: >(x: Array, y: T) => T; // ok, T = Array, satisfies constraint, contextual signature instantiation succeeds >a13 : (x: Base[], y: T) => T >T : T >Array : T[] >Derived : Derived >x : Base[] >Array : T[] >Base : Base >y : T >T : T >T : T a14: (x: { a: T; b: T }) => T; // ok, best common type yields T = {} but that's satisfactory for this signature >a14 : (x: { a: T; b: T; }) => T >T : T >x : { a: T; b: T; } >a : T >T : T >b : T >T : T >T : T }