diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index ad04d6444e521..e5727d0c48c37 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -101,7 +101,6 @@ namespace ts { HasLocals = 1 << 5, IsInterface = 1 << 6, IsObjectLiteralOrClassExpressionMethod = 1 << 7, - IsInferenceContainer = 1 << 8, } const binder = createBinder(); @@ -121,7 +120,6 @@ namespace ts { let container: Node; let containerContainer: Node; // Container one level up let blockScopeContainer: Node; - let inferenceContainer: Node; let lastContainer: Node; let seenThisKeyword: boolean; @@ -190,7 +188,6 @@ namespace ts { container = undefined; containerContainer = undefined; blockScopeContainer = undefined; - inferenceContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; @@ -569,13 +566,6 @@ namespace ts { bindChildren(node); node.flags = seenThisKeyword ? node.flags | NodeFlags.ContainsThis : node.flags & ~NodeFlags.ContainsThis; } - else if (containerFlags & ContainerFlags.IsInferenceContainer) { - const saveInferenceContainer = inferenceContainer; - inferenceContainer = node; - node.locals = undefined; - bindChildren(node); - inferenceContainer = saveInferenceContainer; - } else { bindChildren(node); } @@ -1434,9 +1424,6 @@ namespace ts { case SyntaxKind.MappedType: return ContainerFlags.IsContainer | ContainerFlags.HasLocals; - case SyntaxKind.ConditionalType: - return ContainerFlags.IsInferenceContainer; - case SyntaxKind.SourceFile: return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals; @@ -2638,13 +2625,25 @@ namespace ts { : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } + function getInferTypeContainer(node: Node): ConditionalTypeNode { + while (node) { + const parent = node.parent; + if (parent && parent.kind === SyntaxKind.ConditionalType && (parent).extendsType === node) { + return parent; + } + node = parent; + } + return undefined; + } + function bindTypeParameter(node: TypeParameterDeclaration) { if (node.parent.kind === SyntaxKind.InferType) { - if (inferenceContainer) { - if (!inferenceContainer.locals) { - inferenceContainer.locals = createSymbolTable(); + const container = getInferTypeContainer(node.parent); + if (container) { + if (!container.locals) { + container.locals = createSymbolTable(); } - declareSymbol(inferenceContainer.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); + declareSymbol(container.locals, /*parent*/ undefined, node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes); } else { bindAnonymousDeclaration(node, SymbolFlags.TypeParameter, getDeclarationName(node)); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a0675e957ddc8..49b89904bef56 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2895,7 +2895,8 @@ namespace ts { flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } @@ -2987,6 +2988,9 @@ namespace ts { return typeReferenceToTypeNode(type); } if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { + if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { + return createInferTypeNode(createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } const name = type.symbol ? symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); @@ -3027,7 +3031,10 @@ namespace ts { } if (type.flags & TypeFlags.Conditional) { const checkTypeNode = typeToTypeNodeHelper((type).checkType, context); + const saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = (type).root.inferTypeParameters; const extendsTypeNode = typeToTypeNodeHelper((type).extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; const trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); const falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); @@ -3692,6 +3699,7 @@ namespace ts { // State encounteredError: boolean; symbolStack: Symbol[] | undefined; + inferTypeParameters: TypeParameter[] | undefined; } function isDefaultBindingContext(location: Node) { diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index 3b627a0557f25..01907bdc95b69 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -15,9 +15,9 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS2304: C tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: Cannot find name 'U'. tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(81,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. +tests/cases/conformance/types/conditional/inferTypes1.ts(82,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/conditional/inferTypes1.ts(143,40): error TS2322: Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: Type 'T' is not assignable to type 'string'. ==== tests/cases/conformance/types/conditional/inferTypes1.ts (16 errors) ==== @@ -127,6 +127,7 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(143,40): error TS2322: !!! error TS2304: Cannot find name 'U'. ~ !!! error TS4081: Exported type alias 'T62' has or is using private name 'U'. + type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; type T70 = { x: T }; type T71 = T extends T70 ? T70 : never; diff --git a/tests/baselines/reference/inferTypes1.js b/tests/baselines/reference/inferTypes1.js index 909fbf2998241..f794bb014fac0 100644 --- a/tests/baselines/reference/inferTypes1.js +++ b/tests/baselines/reference/inferTypes1.js @@ -74,6 +74,7 @@ type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number type T60 = infer U; // Error type T61 = infer A extends infer B ? infer C : infer D; // Error type T62 = U extends (infer U)[] ? U : U; // Error +type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; type T70 = { x: T }; type T71 = T extends T70 ? T70 : never; diff --git a/tests/baselines/reference/inferTypes1.symbols b/tests/baselines/reference/inferTypes1.symbols index b1e82a16f5ff0..a786c7a31fb38 100644 --- a/tests/baselines/reference/inferTypes1.symbols +++ b/tests/baselines/reference/inferTypes1.symbols @@ -321,364 +321,373 @@ type T62 = U extends (infer U)[] ? U : U; // Error >U : Symbol(U, Decl(inferTypes1.ts, 74, 30)) >U : Symbol(U, Decl(inferTypes1.ts, 74, 30)) -type T70 = { x: T }; ->T70 : Symbol(T70, Decl(inferTypes1.ts, 74, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 76, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) +type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; +>T63 : Symbol(T63, Decl(inferTypes1.ts, 74, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 75, 30)) +>B : Symbol(B, Decl(inferTypes1.ts, 75, 46)) +>C : Symbol(C, Decl(inferTypes1.ts, 75, 56)) +>D : Symbol(D, Decl(inferTypes1.ts, 75, 66)) -type T71 = T extends T70 ? T70 : never; ->T71 : Symbol(T71, Decl(inferTypes1.ts, 76, 38)) +type T70 = { x: T }; +>T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) >T : Symbol(T, Decl(inferTypes1.ts, 77, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 77, 30)) >T : Symbol(T, Decl(inferTypes1.ts, 77, 9)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 74, 44)) ->U : Symbol(U, Decl(inferTypes1.ts, 77, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 74, 44)) ->U : Symbol(U, Decl(inferTypes1.ts, 77, 33)) -type T72 = { y: T }; ->T72 : Symbol(T72, Decl(inferTypes1.ts, 77, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 79, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) +type T71 = T extends T70 ? T70 : never; +>T71 : Symbol(T71, Decl(inferTypes1.ts, 77, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 78, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 78, 33)) -type T73 = T extends T72 ? T70 : never; // Error ->T73 : Symbol(T73, Decl(inferTypes1.ts, 79, 38)) +type T72 = { y: T }; +>T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) >T : Symbol(T, Decl(inferTypes1.ts, 80, 9)) +>y : Symbol(y, Decl(inferTypes1.ts, 80, 30)) >T : Symbol(T, Decl(inferTypes1.ts, 80, 9)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 77, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 80, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 74, 44)) ->U : Symbol(U, Decl(inferTypes1.ts, 80, 33)) -type T74 = { x: T, y: U }; ->T74 : Symbol(T74, Decl(inferTypes1.ts, 80, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 82, 26)) ->x : Symbol(x, Decl(inferTypes1.ts, 82, 48)) ->T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 82, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 82, 26)) +type T73 = T extends T72 ? T70 : never; // Error +>T73 : Symbol(T73, Decl(inferTypes1.ts, 80, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 81, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 81, 33)) -type T75 = T extends T74 ? T70 | T72 | T74 : never; ->T75 : Symbol(T75, Decl(inferTypes1.ts, 82, 62)) +type T74 = { x: T, y: U }; +>T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) >T : Symbol(T, Decl(inferTypes1.ts, 83, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 83, 26)) +>x : Symbol(x, Decl(inferTypes1.ts, 83, 48)) >T : Symbol(T, Decl(inferTypes1.ts, 83, 9)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 80, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 74, 44)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 77, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 80, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 83, 33), Decl(inferTypes1.ts, 83, 42)) +>y : Symbol(y, Decl(inferTypes1.ts, 83, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 83, 26)) -type T76 = { x: T }; ->T76 : Symbol(T76, Decl(inferTypes1.ts, 83, 84)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 85, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) +type T75 = T extends T74 ? T70 | T72 | T74 : never; +>T75 : Symbol(T75, Decl(inferTypes1.ts, 83, 62)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 75, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 78, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 81, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 84, 33), Decl(inferTypes1.ts, 84, 42)) -type T77 = T extends T76 ? T76 : never; ->T77 : Symbol(T77, Decl(inferTypes1.ts, 85, 48)) +type T76 = { x: T }; +>T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) +>T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 86, 23)) >T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 86, 40)) >T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 83, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 86, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 86, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 83, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 86, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 86, 42)) -type T78 = T extends T76 ? T76 : never; ->T78 : Symbol(T78, Decl(inferTypes1.ts, 86, 66)) +type T77 = T extends T76 ? T76 : never; +>T77 : Symbol(T77, Decl(inferTypes1.ts, 86, 48)) >T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) >T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 83, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 83, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 87, 33), Decl(inferTypes1.ts, 87, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 87, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 87, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 87, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 87, 42)) -type Foo = [T, U]; ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66)) ->T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 89, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 89, 26)) +type T78 = T extends T76 ? T76 : never; +>T78 : Symbol(T78, Decl(inferTypes1.ts, 87, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 84, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 88, 33), Decl(inferTypes1.ts, 88, 42)) -type Bar = T extends Foo ? Foo : never; ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) +type Foo = [T, U]; +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 90, 26)) >T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) >T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 90, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 90, 42)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 87, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 90, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 90, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 90, 26)) + +type Bar = T extends Foo ? Foo : never; +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 91, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 91, 42)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 88, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 91, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 91, 42)) type T90 = Bar<[string, string]>; // [string, string] ->T90 : Symbol(T90, Decl(inferTypes1.ts, 90, 66)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) +>T90 : Symbol(T90, Decl(inferTypes1.ts, 91, 66)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) type T91 = Bar<[string, "a"]>; // [string, "a"] ->T91 : Symbol(T91, Decl(inferTypes1.ts, 92, 33)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) +>T91 : Symbol(T91, Decl(inferTypes1.ts, 93, 33)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"] ->T92 : Symbol(T92, Decl(inferTypes1.ts, 93, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) ->x : Symbol(x, Decl(inferTypes1.ts, 94, 32)) +>T92 : Symbol(T92, Decl(inferTypes1.ts, 94, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 95, 32)) type T93 = Bar<["a", string]>; // never ->T93 : Symbol(T93, Decl(inferTypes1.ts, 94, 46)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) +>T93 : Symbol(T93, Decl(inferTypes1.ts, 95, 46)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) type T94 = Bar<[number, number]>; // never ->T94 : Symbol(T94, Decl(inferTypes1.ts, 95, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 89, 49)) +>T94 : Symbol(T94, Decl(inferTypes1.ts, 96, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 90, 49)) // Example from #21496 type JsonifiedObject = { [K in keyof T]: Jsonified }; ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 96, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 100, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 100, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 100, 21)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 100, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 100, 44)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 97, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 101, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 101, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 101, 44)) type Jsonified = ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) T extends string | number | boolean | null ? T ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) : T extends undefined | Function ? never // undefined and functions are removed ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) >Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) : T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) ->toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 105, 17)) ->R : Symbol(R, Decl(inferTypes1.ts, 105, 33)) ->R : Symbol(R, Decl(inferTypes1.ts, 105, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 106, 17)) +>R : Symbol(R, Decl(inferTypes1.ts, 106, 33)) +>R : Symbol(R, Decl(inferTypes1.ts, 106, 33)) : T extends object ? JsonifiedObject ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 96, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 97, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 103, 15)) : "what is this"; type Example = { ->Example : Symbol(Example, Decl(inferTypes1.ts, 107, 21)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 108, 21)) str: "literalstring", ->str : Symbol(str, Decl(inferTypes1.ts, 109, 16)) +>str : Symbol(str, Decl(inferTypes1.ts, 110, 16)) fn: () => void, ->fn : Symbol(fn, Decl(inferTypes1.ts, 110, 25)) +>fn : Symbol(fn, Decl(inferTypes1.ts, 111, 25)) date: Date, ->date : Symbol(date, Decl(inferTypes1.ts, 111, 19)) +>date : Symbol(date, Decl(inferTypes1.ts, 112, 19)) >Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) customClass: MyClass, ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) obj: { ->obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) prop: "property", ->prop : Symbol(prop, Decl(inferTypes1.ts, 114, 10)) +>prop : Symbol(prop, Decl(inferTypes1.ts, 115, 10)) clz: MyClass, ->clz : Symbol(clz, Decl(inferTypes1.ts, 115, 25)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1)) +>clz : Symbol(clz, Decl(inferTypes1.ts, 116, 25)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) nested: { attr: Date } ->nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) >Date : Symbol(Date, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) }, } declare class MyClass { ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 119, 1)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 120, 1)) toJSON(): "correct"; ->toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 121, 23)) +>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 122, 23)) } type JsonifiedExample = Jsonified; ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 123, 1)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 100, 77)) ->Example : Symbol(Example, Decl(inferTypes1.ts, 107, 21)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 124, 1)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 101, 77)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 108, 21)) declare let ex: JsonifiedExample; ->ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11)) ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 123, 1)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 124, 1)) const z1: "correct" = ex.customClass; ->z1 : Symbol(z1, Decl(inferTypes1.ts, 127, 5)) ->ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11)) ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 112, 15)) +>z1 : Symbol(z1, Decl(inferTypes1.ts, 128, 5)) +>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 113, 15)) const z2: string = ex.obj.nested.attr; ->z2 : Symbol(z2, Decl(inferTypes1.ts, 128, 5)) ->ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17)) ->ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21)) ->ex.obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 126, 11)) ->obj : Symbol(obj, Decl(inferTypes1.ts, 113, 25)) ->nested : Symbol(nested, Decl(inferTypes1.ts, 116, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 117, 17)) +>z2 : Symbol(z2, Decl(inferTypes1.ts, 129, 5)) +>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) +>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) +>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 127, 11)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 114, 25)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 117, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 118, 17)) // Repros from #21631 type A1> = [T, U]; ->A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 132, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 132, 10)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 132, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 132, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 133, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 133, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 133, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 133, 10)) type B1 = S extends A1 ? [T, U] : never; ->B1 : Symbol(B1, Decl(inferTypes1.ts, 132, 44)) ->S : Symbol(S, Decl(inferTypes1.ts, 133, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 133, 8)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 128, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 133, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 133, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 133, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 133, 40)) +>B1 : Symbol(B1, Decl(inferTypes1.ts, 133, 44)) +>S : Symbol(S, Decl(inferTypes1.ts, 134, 8)) +>S : Symbol(S, Decl(inferTypes1.ts, 134, 8)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 129, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 134, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 134, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 134, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 134, 40)) type A2 = [T, U]; ->A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 135, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 135, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 135, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 135, 10)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 136, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 136, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 136, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 136, 10)) type B2 = S extends A2 ? [T, U] : never; ->B2 : Symbol(B2, Decl(inferTypes1.ts, 135, 36)) ->S : Symbol(S, Decl(inferTypes1.ts, 136, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 136, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 136, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 136, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 136, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 136, 40)) - -type C2 = S extends A2 ? [T, U] : never; ->C2 : Symbol(C2, Decl(inferTypes1.ts, 136, 61)) +>B2 : Symbol(B2, Decl(inferTypes1.ts, 136, 36)) >S : Symbol(S, Decl(inferTypes1.ts, 137, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) >S : Symbol(S, Decl(inferTypes1.ts, 137, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 133, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 137, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 137, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 137, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 137, 40)) + +type C2 = S extends A2 ? [T, U] : never; +>C2 : Symbol(C2, Decl(inferTypes1.ts, 137, 61)) +>S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) +>S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 134, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 138, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 138, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 138, 10)) // Repro from #21735 type A = T extends string ? { [P in T]: void; } : T; ->A : Symbol(A, Decl(inferTypes1.ts, 137, 71)) ->T : Symbol(T, Decl(inferTypes1.ts, 141, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 141, 7)) ->P : Symbol(P, Decl(inferTypes1.ts, 141, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 141, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 141, 7)) - -type B = string extends T ? { [P in T]: void; } : T; // Error ->B : Symbol(B, Decl(inferTypes1.ts, 141, 55)) +>A : Symbol(A, Decl(inferTypes1.ts, 138, 71)) >T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) >T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) >P : Symbol(P, Decl(inferTypes1.ts, 142, 34)) >T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) >T : Symbol(T, Decl(inferTypes1.ts, 142, 7)) +type B = string extends T ? { [P in T]: void; } : T; // Error +>B : Symbol(B, Decl(inferTypes1.ts, 142, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) +>P : Symbol(P, Decl(inferTypes1.ts, 143, 34)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) + // Repro from #22302 type MatchingKeys = ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 146, 18)) ->U : Symbol(U, Decl(inferTypes1.ts, 146, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 146, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 146, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 146, 18)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) +>U : Symbol(U, Decl(inferTypes1.ts, 147, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) K extends keyof T ? T[K] extends U ? K : never : never; ->K : Symbol(K, Decl(inferTypes1.ts, 146, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 146, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 146, 18)) ->K : Symbol(K, Decl(inferTypes1.ts, 146, 23)) ->U : Symbol(U, Decl(inferTypes1.ts, 146, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 146, 23)) +>K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 18)) +>K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) +>U : Symbol(U, Decl(inferTypes1.ts, 147, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 147, 23)) type VoidKeys = MatchingKeys; ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 147, 59)) ->T : Symbol(T, Decl(inferTypes1.ts, 149, 14)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 149, 14)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 148, 59)) +>T : Symbol(T, Decl(inferTypes1.ts, 150, 14)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 150, 14)) interface test { ->test : Symbol(test, Decl(inferTypes1.ts, 149, 41)) +>test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) a: 1, ->a : Symbol(test.a, Decl(inferTypes1.ts, 151, 16)) +>a : Symbol(test.a, Decl(inferTypes1.ts, 152, 16)) b: void ->b : Symbol(test.b, Decl(inferTypes1.ts, 152, 9)) +>b : Symbol(test.b, Decl(inferTypes1.ts, 153, 9)) } type T80 = MatchingKeys; ->T80 : Symbol(T80, Decl(inferTypes1.ts, 154, 1)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 142, 55)) ->test : Symbol(test, Decl(inferTypes1.ts, 149, 41)) +>T80 : Symbol(T80, Decl(inferTypes1.ts, 155, 1)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 143, 55)) +>test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) type T81 = VoidKeys; ->T81 : Symbol(T81, Decl(inferTypes1.ts, 156, 36)) ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 147, 59)) ->test : Symbol(test, Decl(inferTypes1.ts, 149, 41)) +>T81 : Symbol(T81, Decl(inferTypes1.ts, 157, 36)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 148, 59)) +>test : Symbol(test, Decl(inferTypes1.ts, 150, 41)) // Repro from #22221 type MustBeString = T; ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 157, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 161, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 161, 18)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 158, 26)) +>T : Symbol(T, Decl(inferTypes1.ts, 162, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 162, 18)) type EnsureIsString = T extends MustBeString ? U : never; ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 162, 20)) ->T : Symbol(T, Decl(inferTypes1.ts, 162, 20)) ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 157, 26)) ->U : Symbol(U, Decl(inferTypes1.ts, 162, 53)) ->U : Symbol(U, Decl(inferTypes1.ts, 162, 53)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 163, 20)) +>T : Symbol(T, Decl(inferTypes1.ts, 163, 20)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 158, 26)) +>U : Symbol(U, Decl(inferTypes1.ts, 163, 53)) +>U : Symbol(U, Decl(inferTypes1.ts, 163, 53)) type Test1 = EnsureIsString<"hello">; // "hello" ->Test1 : Symbol(Test1, Decl(inferTypes1.ts, 162, 69)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40)) +>Test1 : Symbol(Test1, Decl(inferTypes1.ts, 163, 69)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) type Test2 = EnsureIsString<42>; // never ->Test2 : Symbol(Test2, Decl(inferTypes1.ts, 164, 37)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 161, 40)) +>Test2 : Symbol(Test2, Decl(inferTypes1.ts, 165, 37)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 162, 40)) diff --git a/tests/baselines/reference/inferTypes1.types b/tests/baselines/reference/inferTypes1.types index 1d0a48c5169a3..3138341592d0d 100644 --- a/tests/baselines/reference/inferTypes1.types +++ b/tests/baselines/reference/inferTypes1.types @@ -327,6 +327,15 @@ type T62 = U extends (infer U)[] ? U : U; // Error >U : U >U : No type information available! +type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; +>T63 : T63 +>T : T +>T : T +>A : A +>B : B +>C : C +>D : D + type T70 = { x: T }; >T70 : T70 >T : T diff --git a/tests/baselines/reference/inferTypes2.js b/tests/baselines/reference/inferTypes2.js new file mode 100644 index 0000000000000..2b2c318716aa9 --- /dev/null +++ b/tests/baselines/reference/inferTypes2.js @@ -0,0 +1,42 @@ +//// [inferTypes2.ts] +// Repros from #22755 + +export declare function foo(obj: T): T extends () => infer P ? P : never; +export function bar(obj: T) { + return foo(obj); +} + +export type BadNested = { x: T extends number ? T : string }; + +export declare function foo2(obj: T): T extends { [K in keyof BadNested]: BadNested[K] } ? P : never; +export function bar2(obj: T) { + return foo2(obj); +} + + +//// [inferTypes2.js] +"use strict"; +// Repros from #22755 +exports.__esModule = true; +function bar(obj) { + return foo(obj); +} +exports.bar = bar; +function bar2(obj) { + return foo2(obj); +} +exports.bar2 = bar2; + + +//// [inferTypes2.d.ts] +export declare function foo(obj: T): T extends () => infer P ? P : never; +export declare function bar(obj: T): T extends () => infer P ? P : never; +export declare type BadNested = { + x: T extends number ? T : string; +}; +export declare function foo2(obj: T): T extends { + [K in keyof BadNested]: BadNested[K]; +} ? P : never; +export declare function bar2(obj: T): T extends { + x: infer P extends number ? infer P : string; +} ? P : never; diff --git a/tests/baselines/reference/inferTypes2.symbols b/tests/baselines/reference/inferTypes2.symbols new file mode 100644 index 0000000000000..d32d9a7012bee --- /dev/null +++ b/tests/baselines/reference/inferTypes2.symbols @@ -0,0 +1,55 @@ +=== tests/cases/conformance/types/conditional/inferTypes2.ts === +// Repros from #22755 + +export declare function foo(obj: T): T extends () => infer P ? P : never; +>foo : Symbol(foo, Decl(inferTypes2.ts, 0, 0)) +>T : Symbol(T, Decl(inferTypes2.ts, 2, 28)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 2, 31)) +>T : Symbol(T, Decl(inferTypes2.ts, 2, 28)) +>T : Symbol(T, Decl(inferTypes2.ts, 2, 28)) +>P : Symbol(P, Decl(inferTypes2.ts, 2, 61)) +>P : Symbol(P, Decl(inferTypes2.ts, 2, 61)) + +export function bar(obj: T) { +>bar : Symbol(bar, Decl(inferTypes2.ts, 2, 76)) +>T : Symbol(T, Decl(inferTypes2.ts, 3, 20)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 3, 23)) +>T : Symbol(T, Decl(inferTypes2.ts, 3, 20)) + + return foo(obj); +>foo : Symbol(foo, Decl(inferTypes2.ts, 0, 0)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 3, 23)) +} + +export type BadNested = { x: T extends number ? T : string }; +>BadNested : Symbol(BadNested, Decl(inferTypes2.ts, 5, 1)) +>T : Symbol(T, Decl(inferTypes2.ts, 7, 22)) +>x : Symbol(x, Decl(inferTypes2.ts, 7, 28)) +>T : Symbol(T, Decl(inferTypes2.ts, 7, 22)) +>T : Symbol(T, Decl(inferTypes2.ts, 7, 22)) + +export declare function foo2(obj: T): T extends { [K in keyof BadNested]: BadNested[K] } ? P : never; +>foo2 : Symbol(foo2, Decl(inferTypes2.ts, 7, 64)) +>T : Symbol(T, Decl(inferTypes2.ts, 9, 29)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 9, 32)) +>T : Symbol(T, Decl(inferTypes2.ts, 9, 29)) +>T : Symbol(T, Decl(inferTypes2.ts, 9, 29)) +>K : Symbol(K, Decl(inferTypes2.ts, 9, 54)) +>BadNested : Symbol(BadNested, Decl(inferTypes2.ts, 5, 1)) +>P : Symbol(P, Decl(inferTypes2.ts, 9, 80), Decl(inferTypes2.ts, 9, 101)) +>BadNested : Symbol(BadNested, Decl(inferTypes2.ts, 5, 1)) +>P : Symbol(P, Decl(inferTypes2.ts, 9, 80), Decl(inferTypes2.ts, 9, 101)) +>K : Symbol(K, Decl(inferTypes2.ts, 9, 54)) +>P : Symbol(P, Decl(inferTypes2.ts, 9, 80), Decl(inferTypes2.ts, 9, 101)) + +export function bar2(obj: T) { +>bar2 : Symbol(bar2, Decl(inferTypes2.ts, 9, 122)) +>T : Symbol(T, Decl(inferTypes2.ts, 10, 21)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 10, 24)) +>T : Symbol(T, Decl(inferTypes2.ts, 10, 21)) + + return foo2(obj); +>foo2 : Symbol(foo2, Decl(inferTypes2.ts, 7, 64)) +>obj : Symbol(obj, Decl(inferTypes2.ts, 10, 24)) +} + diff --git a/tests/baselines/reference/inferTypes2.types b/tests/baselines/reference/inferTypes2.types new file mode 100644 index 0000000000000..c6ffa871ee973 --- /dev/null +++ b/tests/baselines/reference/inferTypes2.types @@ -0,0 +1,57 @@ +=== tests/cases/conformance/types/conditional/inferTypes2.ts === +// Repros from #22755 + +export declare function foo(obj: T): T extends () => infer P ? P : never; +>foo : (obj: T) => T extends () => infer P ? P : never +>T : T +>obj : T +>T : T +>T : T +>P : P +>P : P + +export function bar(obj: T) { +>bar : (obj: T) => T extends () => infer P ? P : never +>T : T +>obj : T +>T : T + + return foo(obj); +>foo(obj) : T extends () => infer P ? P : never +>foo : (obj: T) => T extends () => infer P ? P : never +>obj : T +} + +export type BadNested = { x: T extends number ? T : string }; +>BadNested : BadNested +>T : T +>x : T extends number ? T : string +>T : T +>T : T + +export declare function foo2(obj: T): T extends { [K in keyof BadNested]: BadNested[K] } ? P : never; +>foo2 : (obj: T) => T extends { x: infer P extends number ? infer P : string; } ? P : never +>T : T +>obj : T +>T : T +>T : T +>K : K +>BadNested : BadNested +>P : P +>BadNested : BadNested +>P : P +>K : K +>P : P + +export function bar2(obj: T) { +>bar2 : (obj: T) => T extends { x: infer P extends number ? infer P : string; } ? P : never +>T : T +>obj : T +>T : T + + return foo2(obj); +>foo2(obj) : T extends { x: infer P extends number ? infer P : string; } ? P : never +>foo2 : (obj: T) => T extends { x: infer P extends number ? infer P : string; } ? P : never +>obj : T +} + diff --git a/tests/cases/conformance/types/conditional/inferTypes1.ts b/tests/cases/conformance/types/conditional/inferTypes1.ts index 8907cf79d9137..6f31b8e49eb9c 100644 --- a/tests/cases/conformance/types/conditional/inferTypes1.ts +++ b/tests/cases/conformance/types/conditional/inferTypes1.ts @@ -76,6 +76,7 @@ type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number type T60 = infer U; // Error type T61 = infer A extends infer B ? infer C : infer D; // Error type T62 = U extends (infer U)[] ? U : U; // Error +type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; type T70 = { x: T }; type T71 = T extends T70 ? T70 : never; diff --git a/tests/cases/conformance/types/conditional/inferTypes2.ts b/tests/cases/conformance/types/conditional/inferTypes2.ts new file mode 100644 index 0000000000000..fbf4ca808336e --- /dev/null +++ b/tests/cases/conformance/types/conditional/inferTypes2.ts @@ -0,0 +1,16 @@ +// @strict: true +// @declaration: true + +// Repros from #22755 + +export declare function foo(obj: T): T extends () => infer P ? P : never; +export function bar(obj: T) { + return foo(obj); +} + +export type BadNested = { x: T extends number ? T : string }; + +export declare function foo2(obj: T): T extends { [K in keyof BadNested]: BadNested[K] } ? P : never; +export function bar2(obj: T) { + return foo2(obj); +}