diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 10247343525a5..6f20830c80f3e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10256,7 +10256,7 @@ namespace ts { const objectFlags = getObjectFlags(type); return !!(type.flags & TypeFlags.TypeVariable || objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || - objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || + objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || objectFlags & ObjectFlags.Mapped || type.flags & TypeFlags.UnionOrIntersection && couldUnionOrIntersectionContainTypeVariables(type)); } @@ -13059,13 +13059,13 @@ namespace ts { return node ? node.contextualMapper : identityMapper; } - // If the given type is an object or union type, if that type has a single signature, and if - // that signature is non-generic, return the signature. Otherwise return undefined. - function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { + // If the given type is an object or union type with a single signature, and if that signature has at + // least as many parameters as the given function, return the signature. Otherwise return undefined. + function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call); if (signatures.length === 1) { const signature = signatures[0]; - if (!signature.typeParameters && !isAritySmaller(signature, node)) { + if (!isAritySmaller(signature, node)) { return signature; } } @@ -13116,12 +13116,12 @@ namespace ts { return undefined; } if (!(type.flags & TypeFlags.Union)) { - return getNonGenericSignature(type, node); + return getContextualCallSignature(type, node); } let signatureList: Signature[]; const types = (type).types; for (const current of types) { - const signature = getNonGenericSignature(current, node); + const signature = getContextualCallSignature(current, node); if (signature) { if (!signatureList) { // This signature will contribute to contextual union signature @@ -14981,11 +14981,21 @@ namespace ts { // We clone the contextual mapper to avoid disturbing a resolution in progress for an // outer call expression. Effectively we just want a snapshot of whatever has been // inferred for any outer call expression so far. - const mapper = cloneTypeMapper(getContextualMapper(node)); - const instantiatedType = instantiateType(contextualType, mapper); - const returnType = getReturnTypeOfSignature(signature); - // Inferences made from return types have lower priority than all other inferences. - inferTypes(context.inferences, instantiatedType, returnType, InferencePriority.ReturnType); + const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node))); + // If the contextual type is a generic pure function type, we instantiate the type with + // its own type parameters and type arguments. This ensures that the type parameters are + // not erased to type any during type inference such that they can be inferred as actual + // types from the contextual type. For example: + // declare function arrayMap(f: (x: T) => U): (a: T[]) => U[]; + // const boxElements: (a: A[]) => { value: A }[] = arrayMap(value => ({ value })); + // Above, the type of the 'value' parameter is inferred to be 'A'. + const contextualSignature = getSingleCallSignature(instantiatedType); + const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ? + getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters)) : + instantiatedType; + const inferenceTargetType = getReturnTypeOfSignature(signature); + // Inferences made from return types have lower priority than all other inferences. + inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); } } diff --git a/tests/baselines/reference/contextualTypingWithGenericSignature.types b/tests/baselines/reference/contextualTypingWithGenericSignature.types index 68c5f3c422d72..e662f2c419252 100644 --- a/tests/baselines/reference/contextualTypingWithGenericSignature.types +++ b/tests/baselines/reference/contextualTypingWithGenericSignature.types @@ -16,10 +16,10 @@ var f2: { }; f2 = (x, y) => { return x } ->f2 = (x, y) => { return x } : (x: any, y: any) => any +>f2 = (x, y) => { return x } : (x: T, y: U) => T >f2 : (x: T, y: U) => T ->(x, y) => { return x } : (x: any, y: any) => any ->x : any ->y : any ->x : any +>(x, y) => { return x } : (x: T, y: U) => T +>x : T +>y : U +>x : T diff --git a/tests/baselines/reference/genericContextualTypes1.js b/tests/baselines/reference/genericContextualTypes1.js new file mode 100644 index 0000000000000..9472412333081 --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.js @@ -0,0 +1,107 @@ +//// [genericContextualTypes1.ts] +type Box = { value: T }; + +declare function wrap(f: (a: A) => B): (a: A) => B; + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; + +declare function list(a: T): T[]; + +declare function unlist(a: T[]): T; + +declare function box(x: V): Box; + +declare function unbox(x: Box): W; + +declare function map(a: T[], f: (x: T) => U): U[]; + +declare function identity(x: T): T; + +declare function zip(a: A, b: B): [A, B]; + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; + +const f00: (x: A) => A[] = list; +const f01: (x: A) => A[] = x => [x]; +const f02: (x: A) => A[] = wrap(list); +const f03: (x: A) => A[] = wrap(x => [x]); + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +const f11: (x: T) => Box = compose(list, box); +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +const f13: (x: Box) => T = compose(unbox, unlist); + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +const f22: (a: A[]) => A[] = arrayMap(identity); +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); + +const f40: (b: B, a: A) => [A, B] = flip(zip); + +// Repro from #16293 + +type fn = (a: A) => A; +const fn: fn = a => a; + + +//// [genericContextualTypes1.js] +"use strict"; +var f00 = list; +var f01 = function (x) { return [x]; }; +var f02 = wrap(list); +var f03 = wrap(function (x) { return [x]; }); +var f10 = compose(function (a) { return list(a); }, function (b) { return box(b); }); +var f11 = compose(list, box); +var f12 = compose(function (a) { return unbox(a); }, function (b) { return unlist(b); }); +var f13 = compose(unbox, unlist); +var arrayMap = function (f) { return function (a) { return a.map(f); }; }; +var arrayFilter = function (f) { return function (a) { return a.filter(f); }; }; +var f20 = arrayMap(function (x) { return x.length; }); +var f21 = arrayMap(function (x) { return [x]; }); +var f22 = arrayMap(identity); +var f23 = arrayMap(function (value) { return ({ value: value }); }); +var f30 = arrayFilter(function (x) { return x.length > 10; }); +var f31 = arrayFilter(function (x) { return x.value > 10; }); +var f40 = flip(zip); +var fn = function (a) { return a; }; + + +//// [genericContextualTypes1.d.ts] +declare type Box = { + value: T; +}; +declare function wrap(f: (a: A) => B): (a: A) => B; +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +declare function list(a: T): T[]; +declare function unlist(a: T[]): T; +declare function box(x: V): Box; +declare function unbox(x: Box): W; +declare function map(a: T[], f: (x: T) => U): U[]; +declare function identity(x: T): T; +declare function zip(a: A, b: B): [A, B]; +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +declare const f00: (x: A) => A[]; +declare const f01: (x: A) => A[]; +declare const f02: (x: A) => A[]; +declare const f03: (x: A) => A[]; +declare const f10: (x: T) => Box; +declare const f11: (x: T) => Box; +declare const f12: (x: Box) => T; +declare const f13: (x: Box) => T; +declare const arrayMap: (f: (x: T) => U) => (a: T[]) => U[]; +declare const arrayFilter: (f: (x: T) => boolean) => (a: T[]) => T[]; +declare const f20: (a: string[]) => number[]; +declare const f21: (a: A[]) => A[][]; +declare const f22: (a: A[]) => A[]; +declare const f23: (a: A[]) => Box[]; +declare const f30: (a: string[]) => string[]; +declare const f31: >(a: T[]) => T[]; +declare const f40: (b: B, a: A) => [A, B]; +declare type fn = (a: A) => A; +declare const fn: fn; diff --git a/tests/baselines/reference/genericContextualTypes1.symbols b/tests/baselines/reference/genericContextualTypes1.symbols new file mode 100644 index 0000000000000..29d8766abca3a --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.symbols @@ -0,0 +1,318 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts === +type Box = { value: T }; +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 0, 9)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 0, 9)) + +declare function wrap(f: (a: A) => B): (a: A) => B; +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 2, 28)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 2, 32)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 2, 46)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 2, 22)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 2, 24)) + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 4, 34)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 4, 38)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>g : Symbol(g, Decl(genericContextualTypes1.ts, 4, 49)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 4, 54)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 4, 27)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 4, 68)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 4, 25)) +>C : Symbol(C, Decl(genericContextualTypes1.ts, 4, 30)) + +declare function list(a: T): T[]; +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 6, 25)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 6, 22)) + +declare function unlist(a: T[]): T; +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 8, 27)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 8, 24)) + +declare function box(x: V): Box; +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 10, 24)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>V : Symbol(V, Decl(genericContextualTypes1.ts, 10, 21)) + +declare function unbox(x: Box): W; +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 12, 26)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) +>W : Symbol(W, Decl(genericContextualTypes1.ts, 12, 23)) + +declare function map(a: T[], f: (x: T) => U): U[]; +>map : Symbol(map, Decl(genericContextualTypes1.ts, 12, 40)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 14, 27)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 14, 34)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 14, 39)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 14, 21)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 14, 23)) + +declare function identity(x: T): T; +>identity : Symbol(identity, Decl(genericContextualTypes1.ts, 14, 56)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 16, 29)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 16, 26)) + +declare function zip(a: A, b: B): [A, B]; +>zip : Symbol(zip, Decl(genericContextualTypes1.ts, 16, 38)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 18, 27)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 18, 32)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 18, 21)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 18, 23)) + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +>flip : Symbol(flip, Decl(genericContextualTypes1.ts, 18, 47)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 20, 31)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 20, 35)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>y : Symbol(y, Decl(genericContextualTypes1.ts, 20, 40)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) +>y : Symbol(y, Decl(genericContextualTypes1.ts, 20, 55)) +>Y : Symbol(Y, Decl(genericContextualTypes1.ts, 20, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 20, 60)) +>X : Symbol(X, Decl(genericContextualTypes1.ts, 20, 22)) +>Z : Symbol(Z, Decl(genericContextualTypes1.ts, 20, 27)) + +const f00: (x: A) => A[] = list; +>f00 : Symbol(f00, Decl(genericContextualTypes1.ts, 22, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 22, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 22, 12)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) + +const f01: (x: A) => A[] = x => [x]; +>f01 : Symbol(f01, Decl(genericContextualTypes1.ts, 23, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 23, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 29)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 23, 29)) + +const f02: (x: A) => A[] = wrap(list); +>f02 : Symbol(f02, Decl(genericContextualTypes1.ts, 24, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 24, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 24, 12)) +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) + +const f03: (x: A) => A[] = wrap(x => [x]); +>f03 : Symbol(f03, Decl(genericContextualTypes1.ts, 25, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 25, 12)) +>wrap : Symbol(wrap, Decl(genericContextualTypes1.ts, 0, 27)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 35)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 25, 35)) + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +>f10 : Symbol(f10, Decl(genericContextualTypes1.ts, 27, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 27, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 27, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 27, 43)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 27, 43)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 27, 56)) +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 27, 56)) + +const f11: (x: T) => Box = compose(list, box); +>f11 : Symbol(f11, Decl(genericContextualTypes1.ts, 28, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 28, 15)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 28, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>list : Symbol(list, Decl(genericContextualTypes1.ts, 4, 79)) +>box : Symbol(box, Decl(genericContextualTypes1.ts, 8, 38)) + +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +>f12 : Symbol(f12, Decl(genericContextualTypes1.ts, 29, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 29, 15)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 29, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 29, 43)) +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 29, 43)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 29, 57)) +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 29, 57)) + +const f13: (x: Box) => T = compose(unbox, unlist); +>f13 : Symbol(f13, Decl(genericContextualTypes1.ts, 30, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 30, 15)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 30, 12)) +>compose : Symbol(compose, Decl(genericContextualTypes1.ts, 2, 57)) +>unbox : Symbol(unbox, Decl(genericContextualTypes1.ts, 10, 38)) +>unlist : Symbol(unlist, Decl(genericContextualTypes1.ts, 6, 36)) + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 32, 20)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 32, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 32, 28)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>U : Symbol(U, Decl(genericContextualTypes1.ts, 32, 20)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 32, 44)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 32, 18)) +>a.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 32, 44)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 32, 24)) + +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 33, 24)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 33, 28)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 33, 50)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 33, 21)) +>a.filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 33, 50)) +>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>f : Symbol(f, Decl(genericContextualTypes1.ts, 33, 24)) + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +>f20 : Symbol(f20, Decl(genericContextualTypes1.ts, 35, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 35, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 35, 48)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 35, 48)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +>f21 : Symbol(f21, Decl(genericContextualTypes1.ts, 36, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 36, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 36, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 36, 43)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 36, 43)) + +const f22: (a: A[]) => A[] = arrayMap(identity); +>f22 : Symbol(f22, Decl(genericContextualTypes1.ts, 37, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 37, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 37, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>identity : Symbol(identity, Decl(genericContextualTypes1.ts, 14, 56)) + +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); +>f23 : Symbol(f23, Decl(genericContextualTypes1.ts, 38, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 38, 15)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 38, 12)) +>arrayMap : Symbol(arrayMap, Decl(genericContextualTypes1.ts, 32, 5)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 38, 46)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 38, 57)) + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +>f30 : Symbol(f30, Decl(genericContextualTypes1.ts, 40, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 40, 12)) +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 40, 51)) +>x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 40, 51)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); +>f31 : Symbol(f31, Decl(genericContextualTypes1.ts, 41, 5)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>Box : Symbol(Box, Decl(genericContextualTypes1.ts, 0, 0)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 41, 35)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>T : Symbol(T, Decl(genericContextualTypes1.ts, 41, 12)) +>arrayFilter : Symbol(arrayFilter, Decl(genericContextualTypes1.ts, 33, 5)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 41, 64)) +>x.value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) +>x : Symbol(x, Decl(genericContextualTypes1.ts, 41, 64)) +>value : Symbol(value, Decl(genericContextualTypes1.ts, 0, 15)) + +const f40: (b: B, a: A) => [A, B] = flip(zip); +>f40 : Symbol(f40, Decl(genericContextualTypes1.ts, 43, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>b : Symbol(b, Decl(genericContextualTypes1.ts, 43, 18)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 43, 23)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 43, 12)) +>B : Symbol(B, Decl(genericContextualTypes1.ts, 43, 14)) +>flip : Symbol(flip, Decl(genericContextualTypes1.ts, 18, 47)) +>zip : Symbol(zip, Decl(genericContextualTypes1.ts, 16, 38)) + +// Repro from #16293 + +type fn = (a: A) => A; +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 47, 14)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) +>A : Symbol(A, Decl(genericContextualTypes1.ts, 47, 11)) + +const fn: fn = a => a; +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>fn : Symbol(fn, Decl(genericContextualTypes1.ts, 43, 52), Decl(genericContextualTypes1.ts, 48, 5)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 48, 14)) +>a : Symbol(a, Decl(genericContextualTypes1.ts, 48, 14)) + diff --git a/tests/baselines/reference/genericContextualTypes1.types b/tests/baselines/reference/genericContextualTypes1.types new file mode 100644 index 0000000000000..4aedcd6e81b22 --- /dev/null +++ b/tests/baselines/reference/genericContextualTypes1.types @@ -0,0 +1,362 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts === +type Box = { value: T }; +>Box : Box +>T : T +>value : T +>T : T + +declare function wrap(f: (a: A) => B): (a: A) => B; +>wrap : (f: (a: A) => B) => (a: A) => B +>A : A +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>a : A +>A : A +>B : B + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>A : A +>B : B +>C : C +>f : (a: A) => B +>a : A +>A : A +>B : B +>g : (b: B) => C +>b : B +>B : B +>C : C +>a : A +>A : A +>C : C + +declare function list(a: T): T[]; +>list : (a: T) => T[] +>T : T +>a : T +>T : T +>T : T + +declare function unlist(a: T[]): T; +>unlist : (a: T[]) => T +>T : T +>a : T[] +>T : T +>T : T + +declare function box(x: V): Box; +>box : (x: V) => Box +>V : V +>x : V +>V : V +>Box : Box +>V : V + +declare function unbox(x: Box): W; +>unbox : (x: Box) => W +>W : W +>x : Box +>Box : Box +>W : W +>W : W + +declare function map(a: T[], f: (x: T) => U): U[]; +>map : (a: T[], f: (x: T) => U) => U[] +>T : T +>U : U +>a : T[] +>T : T +>f : (x: T) => U +>x : T +>T : T +>U : U +>U : U + +declare function identity(x: T): T; +>identity : (x: T) => T +>T : T +>x : T +>T : T +>T : T + +declare function zip(a: A, b: B): [A, B]; +>zip : (a: A, b: B) => [A, B] +>A : A +>B : B +>a : A +>A : A +>b : B +>B : B +>A : A +>B : B + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; +>flip : (f: (x: X, y: Y) => Z) => (y: Y, x: X) => Z +>X : X +>Y : Y +>Z : Z +>f : (x: X, y: Y) => Z +>x : X +>X : X +>y : Y +>Y : Y +>Z : Z +>y : Y +>Y : Y +>x : X +>X : X +>Z : Z + +const f00: (x: A) => A[] = list; +>f00 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>list : (a: T) => T[] + +const f01: (x: A) => A[] = x => [x]; +>f01 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f02: (x: A) => A[] = wrap(list); +>f02 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>wrap(list) : (a: A) => A[] +>wrap : (f: (a: A) => B) => (a: A) => B +>list : (a: T) => T[] + +const f03: (x: A) => A[] = wrap(x => [x]); +>f03 : (x: A) => A[] +>A : A +>x : A +>A : A +>A : A +>wrap(x => [x]) : (a: A) => A[] +>wrap : (f: (a: A) => B) => (a: A) => B +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +>f10 : (x: T) => Box +>T : T +>x : T +>T : T +>Box : Box +>T : T +>compose(a => list(a), b => box(b)) : (a: T) => Box +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>a => list(a) : (a: T) => T[] +>a : T +>list(a) : T[] +>list : (a: T) => T[] +>a : T +>b => box(b) : (b: T[]) => Box +>b : T[] +>box(b) : Box +>box : (x: V) => Box +>b : T[] + +const f11: (x: T) => Box = compose(list, box); +>f11 : (x: T) => Box +>T : T +>x : T +>T : T +>Box : Box +>T : T +>compose(list, box) : (a: T) => Box +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>list : (a: T) => T[] +>box : (x: V) => Box + +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +>f12 : (x: Box) => T +>T : T +>x : Box +>Box : Box +>T : T +>T : T +>compose(a => unbox(a), b => unlist(b)) : (a: Box) => T +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>a => unbox(a) : (a: Box) => T[] +>a : Box +>unbox(a) : T[] +>unbox : (x: Box) => W +>a : Box +>b => unlist(b) : (b: T[]) => T +>b : T[] +>unlist(b) : T +>unlist : (a: T[]) => T +>b : T[] + +const f13: (x: Box) => T = compose(unbox, unlist); +>f13 : (x: Box) => T +>T : T +>x : Box +>Box : Box +>T : T +>T : T +>compose(unbox, unlist) : (a: Box) => T +>compose : (f: (a: A) => B, g: (b: B) => C) => (a: A) => C +>unbox : (x: Box) => W +>unlist : (a: T[]) => T + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>(f: (x: T) => U) => (a: T[]) => a.map(f) : (f: (x: T) => U) => (a: T[]) => U[] +>T : T +>U : U +>f : (x: T) => U +>x : T +>T : T +>U : U +>(a: T[]) => a.map(f) : (a: T[]) => U[] +>a : T[] +>T : T +>a.map(f) : U[] +>a.map : (callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[] +>a : T[] +>map : (callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any) => U[] +>f : (x: T) => U + +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>(f: (x: T) => boolean) => (a: T[]) => a.filter(f) : (f: (x: T) => boolean) => (a: T[]) => T[] +>T : T +>f : (x: T) => boolean +>x : T +>T : T +>(a: T[]) => a.filter(f) : (a: T[]) => T[] +>a : T[] +>T : T +>a.filter(f) : T[] +>a.filter : { (callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; } +>a : T[] +>filter : { (callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[]; } +>f : (x: T) => boolean + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +>f20 : (a: string[]) => number[] +>a : string[] +>arrayMap(x => x.length) : (a: string[]) => number[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>x => x.length : (x: string) => number +>x : string +>x.length : number +>x : string +>length : number + +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +>f21 : (a: A[]) => A[][] +>A : A +>a : A[] +>A : A +>A : A +>arrayMap(x => [x]) : (a: A[]) => A[][] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>x => [x] : (x: A) => A[] +>x : A +>[x] : A[] +>x : A + +const f22: (a: A[]) => A[] = arrayMap(identity); +>f22 : (a: A[]) => A[] +>A : A +>a : A[] +>A : A +>A : A +>arrayMap(identity) : (a: A[]) => A[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>identity : (x: T) => T + +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); +>f23 : (a: A[]) => Box[] +>A : A +>a : A[] +>A : A +>Box : Box +>A : A +>arrayMap(value => ({ value })) : (a: A[]) => { value: A; }[] +>arrayMap : (f: (x: T) => U) => (a: T[]) => U[] +>value => ({ value }) : (value: A) => { value: A; } +>value : A +>({ value }) : { value: A; } +>{ value } : { value: A; } +>value : A + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +>f30 : (a: string[]) => string[] +>a : string[] +>arrayFilter(x => x.length > 10) : (a: string[]) => string[] +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>x => x.length > 10 : (x: string) => boolean +>x : string +>x.length > 10 : boolean +>x.length : number +>x : string +>length : number +>10 : 10 + +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); +>f31 : >(a: T[]) => T[] +>T : T +>Box : Box +>a : T[] +>T : T +>T : T +>arrayFilter(x => x.value > 10) : (a: T[]) => T[] +>arrayFilter : (f: (x: T) => boolean) => (a: T[]) => T[] +>x => x.value > 10 : (x: T) => boolean +>x : T +>x.value > 10 : boolean +>x.value : number +>x : T +>value : number +>10 : 10 + +const f40: (b: B, a: A) => [A, B] = flip(zip); +>f40 : (b: B, a: A) => [A, B] +>A : A +>B : B +>b : B +>B : B +>a : A +>A : A +>A : A +>B : B +>flip(zip) : (y: B, x: A) => [A, B] +>flip : (f: (x: X, y: Y) => Z) => (y: Y, x: X) => Z +>zip : (a: A, b: B) => [A, B] + +// Repro from #16293 + +type fn = (a: A) => A; +>fn : fn +>A : A +>a : A +>A : A +>A : A + +const fn: fn = a => a; +>fn : fn +>fn : fn +>a => a : (a: A) => A +>a : A +>a : A + diff --git a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types index 3a3afebb9ac18..d6f64bdc933aa 100644 --- a/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types +++ b/tests/baselines/reference/genericFunctionHasFreshTypeArgs.types @@ -9,13 +9,13 @@ function f(p: (x: T) => void) { }; f(x => f(y => x = y)); >f(x => f(y => x = y)) : void >f : (p: (x: T) => void) => void ->x => f(y => x = y) : (x: any) => void ->x : any +>x => f(y => x = y) : (x: T) => void +>x : T >f(y => x = y) : void >f : (p: (x: T) => void) => void ->y => x = y : (y: any) => any ->y : any ->x = y : any ->x : any ->y : any +>y => x = y : (y: T) => T +>y : T +>x = y : T +>x : T +>y : T diff --git a/tests/baselines/reference/genericTypeAssertions3.types b/tests/baselines/reference/genericTypeAssertions3.types index 9f7facc8d478d..e46dd4aaa4e50 100644 --- a/tests/baselines/reference/genericTypeAssertions3.types +++ b/tests/baselines/reference/genericTypeAssertions3.types @@ -6,9 +6,9 @@ var r = < (x: T) => T > ((x) => { return null; }); // bug was 'could not find >x : T >T : T >T : T ->((x) => { return null; }) : (x: any) => any ->(x) => { return null; } : (x: any) => any ->x : any +>((x) => { return null; }) : (x: T) => any +>(x) => { return null; } : (x: T) => any +>x : T >null : null var s = < (x: T) => T > ((x: any) => { return null; }); // no error diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt b/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt deleted file mode 100644 index 0c64c3e612535..0000000000000 --- a/tests/baselines/reference/implicitAnyGenericTypeInference.errors.txt +++ /dev/null @@ -1,16 +0,0 @@ -tests/cases/compiler/implicitAnyGenericTypeInference.ts(6,19): error TS7006: Parameter 'x' implicitly has an 'any' type. -tests/cases/compiler/implicitAnyGenericTypeInference.ts(6,22): error TS7006: Parameter 'y' implicitly has an 'any' type. - - -==== tests/cases/compiler/implicitAnyGenericTypeInference.ts (2 errors) ==== - interface Comparer { - compareTo(x: T, y: U): U; - } - - var c: Comparer; - c = { compareTo: (x, y) => { return y; } }; - ~ -!!! error TS7006: Parameter 'x' implicitly has an 'any' type. - ~ -!!! error TS7006: Parameter 'y' implicitly has an 'any' type. - var r = c.compareTo(1, ''); \ No newline at end of file diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.symbols b/tests/baselines/reference/implicitAnyGenericTypeInference.symbols new file mode 100644 index 0000000000000..e56b68a713457 --- /dev/null +++ b/tests/baselines/reference/implicitAnyGenericTypeInference.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/implicitAnyGenericTypeInference.ts === +interface Comparer { +>Comparer : Symbol(Comparer, Decl(implicitAnyGenericTypeInference.ts, 0, 0)) +>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 0, 19)) + + compareTo(x: T, y: U): U; +>compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +>x : Symbol(x, Decl(implicitAnyGenericTypeInference.ts, 1, 17)) +>T : Symbol(T, Decl(implicitAnyGenericTypeInference.ts, 0, 19)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 1, 22)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +>U : Symbol(U, Decl(implicitAnyGenericTypeInference.ts, 1, 14)) +} + +var c: Comparer; +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>Comparer : Symbol(Comparer, Decl(implicitAnyGenericTypeInference.ts, 0, 0)) + +c = { compareTo: (x, y) => { return y; } }; +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>compareTo : Symbol(compareTo, Decl(implicitAnyGenericTypeInference.ts, 5, 5)) +>x : Symbol(x, Decl(implicitAnyGenericTypeInference.ts, 5, 18)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 5, 20)) +>y : Symbol(y, Decl(implicitAnyGenericTypeInference.ts, 5, 20)) + +var r = c.compareTo(1, ''); +>r : Symbol(r, Decl(implicitAnyGenericTypeInference.ts, 6, 3)) +>c.compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) +>c : Symbol(c, Decl(implicitAnyGenericTypeInference.ts, 4, 3)) +>compareTo : Symbol(Comparer.compareTo, Decl(implicitAnyGenericTypeInference.ts, 0, 23)) + diff --git a/tests/baselines/reference/implicitAnyGenericTypeInference.types b/tests/baselines/reference/implicitAnyGenericTypeInference.types new file mode 100644 index 0000000000000..4124c729f14b1 --- /dev/null +++ b/tests/baselines/reference/implicitAnyGenericTypeInference.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/implicitAnyGenericTypeInference.ts === +interface Comparer { +>Comparer : Comparer +>T : T + + compareTo(x: T, y: U): U; +>compareTo : (x: T, y: U) => U +>U : U +>x : T +>T : T +>y : U +>U : U +>U : U +} + +var c: Comparer; +>c : Comparer +>Comparer : Comparer + +c = { compareTo: (x, y) => { return y; } }; +>c = { compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; } +>c : Comparer +>{ compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; } +>compareTo : (x: any, y: U) => U +>(x, y) => { return y; } : (x: any, y: U) => U +>x : any +>y : U +>y : U + +var r = c.compareTo(1, ''); +>r : string +>c.compareTo(1, '') : "" +>c.compareTo : (x: any, y: U) => U +>c : Comparer +>compareTo : (x: any, y: U) => U +>1 : 1 +>'' : "" + diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts b/tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts new file mode 100644 index 0000000000000..6d937adcbf626 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/genericContextualTypes1.ts @@ -0,0 +1,52 @@ +// @strict: true +// @declaration: true + +type Box = { value: T }; + +declare function wrap(f: (a: A) => B): (a: A) => B; + +declare function compose(f: (a: A) => B, g: (b: B) => C): (a: A) => C; + +declare function list(a: T): T[]; + +declare function unlist(a: T[]): T; + +declare function box(x: V): Box; + +declare function unbox(x: Box): W; + +declare function map(a: T[], f: (x: T) => U): U[]; + +declare function identity(x: T): T; + +declare function zip(a: A, b: B): [A, B]; + +declare function flip(f: (x: X, y: Y) => Z): (y: Y, x: X) => Z; + +const f00: (x: A) => A[] = list; +const f01: (x: A) => A[] = x => [x]; +const f02: (x: A) => A[] = wrap(list); +const f03: (x: A) => A[] = wrap(x => [x]); + +const f10: (x: T) => Box = compose(a => list(a), b => box(b)); +const f11: (x: T) => Box = compose(list, box); +const f12: (x: Box) => T = compose(a => unbox(a), b => unlist(b)); +const f13: (x: Box) => T = compose(unbox, unlist); + +const arrayMap = (f: (x: T) => U) => (a: T[]) => a.map(f); +const arrayFilter = (f: (x: T) => boolean) => (a: T[]) => a.filter(f); + +const f20: (a: string[]) => number[] = arrayMap(x => x.length); +const f21: (a: A[]) => A[][] = arrayMap(x => [x]); +const f22: (a: A[]) => A[] = arrayMap(identity); +const f23: (a: A[]) => Box[] = arrayMap(value => ({ value })); + +const f30: (a: string[]) => string[] = arrayFilter(x => x.length > 10); +const f31: >(a: T[]) => T[] = arrayFilter(x => x.value > 10); + +const f40: (b: B, a: A) => [A, B] = flip(zip); + +// Repro from #16293 + +type fn = (a: A) => A; +const fn: fn = a => a; diff --git a/tests/cases/fourslash/contextualTypingOfGenericCallSignatures2.ts b/tests/cases/fourslash/contextualTypingOfGenericCallSignatures2.ts index 0f610a2a53910..efb26cb3af1a4 100644 --- a/tests/cases/fourslash/contextualTypingOfGenericCallSignatures2.ts +++ b/tests/cases/fourslash/contextualTypingOfGenericCallSignatures2.ts @@ -7,5 +7,5 @@ ////// x should not be contextually typed so this should be an error ////f6(/**/x => x()) -verify.quickInfoAt("", "(parameter) x: any"); +verify.quickInfoAt("", "(parameter) x: T extends I"); verify.numberOfErrorsInCurrentFile(1); diff --git a/tests/cases/fourslash/contextuallyTypedFunctionExpressionGeneric1.ts b/tests/cases/fourslash/contextuallyTypedFunctionExpressionGeneric1.ts index a33e2cc5e7aab..bfc4d7ea6fdf4 100644 --- a/tests/cases/fourslash/contextuallyTypedFunctionExpressionGeneric1.ts +++ b/tests/cases/fourslash/contextuallyTypedFunctionExpressionGeneric1.ts @@ -1,17 +1,17 @@ /// ////interface Comparable { -//// compareTo(other: T): T; +//// compareTo(other: T): T; ////} ////interface Comparer { -//// >(x: T, y: T): T; +//// >(x: T, y: T): T; ////} ////var max2: Comparer = (x/*1*/x, y/*2*/y) => { return x/*3*/x.compareTo(y/*4*/y) }; verify.quickInfos({ - 1: "(parameter) xx: any", - 2: "(parameter) yy: any", - 3: "(parameter) xx: any", - 4: "(parameter) yy: any" + 1: "(parameter) xx: T extends Comparable", + 2: "(parameter) yy: T extends Comparable", + 3: "(parameter) xx: T extends Comparable", + 4: "(parameter) yy: T extends Comparable" });