diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 06b519ff4b898..0d069ac41548a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25729,6 +25729,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { topLevel: true, isFixed: false, impliedArity: undefined, + indexes: undefined, }; } @@ -25742,6 +25743,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { topLevel: inference.topLevel, isFixed: inference.isFixed, impliedArity: inference.impliedArity, + indexes: inference.indexes && inference.indexes.slice(), }; } @@ -25894,7 +25896,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); inferTypes([inference], sourceType, templateType); - return getTypeFromInference(inference) || unknownType; + return getTypeFromInference(inference) || (inference.indexes ? getIntersectionType(inference.indexes) : unknownType); } function inferReverseMappedType(source: Type, target: MappedType, constraint: IndexType): Type | undefined { @@ -26347,6 +26349,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inferFromTypes((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType); inferFromTypes((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType); } + else if (!(priority & InferencePriority.NakedTypeVariable) && target.flags & TypeFlags.IndexedAccess) { + if (isFromInferenceBlockedSource(source)) { + return; + } + const inference = getInferenceInfoForType(getActualTypeVariable((target as IndexedAccessType).objectType)); + if (inference) { + if (getObjectFlags(source) & ObjectFlags.NonInferrableType || source === nonInferrableAnyType) { + return; + } + if (!inference.isFixed) { + // Instantiates instance of `type PartialInference = ({[K in Keys]: {[K1 in K]: T}})[Keys];` + // Where `T` is `source` and `Keys` is `target.indexType` + const inferenceTypeSymbol = getGlobalSymbol("PartialInference" as __String, SymbolFlags.Type, Diagnostics.Cannot_find_global_type_0); + const inferenceType = inferenceTypeSymbol && getDeclaredTypeOfSymbol(inferenceTypeSymbol); + if (inferenceType && inferenceType !== unknownType) { + const mapper = createTypeMapper(getSymbolLinks(inferenceTypeSymbol).typeParameters!, [source, (target as IndexedAccessType).indexType]); + inference.indexes = append(inference.indexes, instantiateType(inferenceType, mapper)); + } + } + } + } else if (source.flags & TypeFlags.StringMapping && target.flags & TypeFlags.StringMapping) { if ((source as StringMappingType).symbol === (target as StringMappingType).symbol) { inferFromTypes((source as StringMappingType).type, (target as StringMappingType).type); @@ -27019,6 +27042,39 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inferredType = preferCovariantType ? inferredCovariantType : inferredContravariantType; fallbackType = preferCovariantType ? inferredContravariantType : inferredCovariantType; } + else if (inference.indexes) { + let aggregateInference = getIntersectionType(inference.indexes); + const constraint = getConstraintOfTypeParameter(inference.typeParameter); + if (constraint) { + const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper); + if (instantiatedConstraint.flags & TypeFlags.Union && !context.compareTypes(aggregateInference, getTypeWithThisArgument(instantiatedConstraint, aggregateInference))) { + const discriminantProps = findDiscriminantProperties(getPropertiesOfType(aggregateInference), instantiatedConstraint); + if (discriminantProps) { + let match: Type | undefined; + findDiscriminant: + for (const p of discriminantProps) { + const candidatePropType = getTypeOfPropertyOfType(aggregateInference, p.escapedName); + for (const type of (instantiatedConstraint as UnionType).types) { + const propType = getTypeOfPropertyOfType(type, p.escapedName); + if (propType && candidatePropType && checkTypeAssignableTo(candidatePropType, propType, /*errorNode*/ undefined)) { + if (match && match !== type) { + match = undefined; + break findDiscriminant; + } + else { + match = type; + } + } + } + } + if (match) { + aggregateInference = getSpreadType(match, aggregateInference, /*symbol*/ undefined, /*propegatedFlags*/ 0, /*readonly*/ false); + } + } + } + } + inferredType = aggregateInference; + } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. inferredType = silentNeverType; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 590911b3f6e99..76d1aced447c5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7043,6 +7043,7 @@ export interface InferenceInfo { typeParameter: TypeParameter; // Type parameter for which inferences are being made candidates: Type[] | undefined; // Candidates in covariant positions (or undefined) contraCandidates: Type[] | undefined; // Candidates in contravariant positions (or undefined) + indexes: Type[] | undefined; // Partial candidates created by indexed accesses inferredType?: Type; // Cache for resolved inferred type priority?: InferencePriority; // Priority of current inference set topLevel: boolean; // True if all inferences are to top level occurrences diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 8af5de8cdc5ba..46ffbf08032b5 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1295,6 +1295,7 @@ export namespace Completion { typeEntry("Uncapitalize"), typeEntry("NoInfer"), interfaceEntry("ThisType"), + typeEntry("PartialInference"), varEntry("ArrayBuffer"), interfaceEntry("ArrayBufferTypes"), typeEntry("ArrayBufferLike"), diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 33bbb99147490..21a8ead635e73 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1659,6 +1659,15 @@ type NoInfer = intrinsic; */ interface ThisType {} +/** + * Type instantiated to perform partial inferences from indexed accesses + */ +type PartialInference = ({ + [K in Keys]: { + [K1 in K]: T; + }; +})[Keys]; + /** * Stores types to be used with WeakSet, WeakMap, WeakRef, and FinalizationRegistry */ diff --git a/tests/baselines/reference/completionsCommitCharactersGlobal.baseline b/tests/baselines/reference/completionsCommitCharactersGlobal.baseline index 03147604cbf99..787c5b8ee480a 100644 --- a/tests/baselines/reference/completionsCommitCharactersGlobal.baseline +++ b/tests/baselines/reference/completionsCommitCharactersGlobal.baseline @@ -2692,6 +2692,7 @@ // | type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void // | type Parameters any> = T extends (...args: infer P) => any ? P : never // | type Partial = { [P in keyof T]?: T[P]; } +// | type PartialInference = { [K in Keys]: { [K1 in K]: T; }; }[Keys] // | type Pick = { [P in K]: T[P]; } // | interface Promise // | type PromiseConstructorLike = new (executor: (resolve: (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseLike @@ -2872,6 +2873,7 @@ // | type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void // | type Parameters any> = T extends (...args: infer P) => any ? P : never // | type Partial = { [P in keyof T]?: T[P]; } +// | type PartialInference = { [K in Keys]: { [K1 in K]: T; }; }[Keys] // | type Pick = { [P in K]: T[P]; } // | interface Promise // | type PromiseConstructorLike = new (executor: (resolve: (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseLike @@ -73582,6 +73584,212 @@ } ] }, + { + "name": "PartialInference", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15", + "displayParts": [ + { + "text": "type", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "PartialInference", + "kind": "aliasName" + }, + { + "text": "<", + "kind": "punctuation" + }, + { + "text": "T", + "kind": "typeParameterName" + }, + { + "text": ",", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "extends", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ">", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "K", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "in", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "K1", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "in", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "K", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "T", + "kind": "typeParameterName" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "}", + "kind": "punctuation" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "}", + "kind": "punctuation" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + } + ], + "documentation": [ + { + "text": "Type instantiated to perform partial inferences from indexed accesses", + "kind": "text" + } + ] + }, { "name": "Pick", "kind": "type", @@ -82569,6 +82777,212 @@ } ] }, + { + "name": "PartialInference", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15", + "displayParts": [ + { + "text": "type", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "PartialInference", + "kind": "aliasName" + }, + { + "text": "<", + "kind": "punctuation" + }, + { + "text": "T", + "kind": "typeParameterName" + }, + { + "text": ",", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "extends", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "string", + "kind": "keyword" + }, + { + "text": ">", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "=", + "kind": "operator" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "K", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "in", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "{", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "K1", + "kind": "typeParameterName" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "in", + "kind": "keyword" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "K", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + }, + { + "text": ":", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "T", + "kind": "typeParameterName" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "}", + "kind": "punctuation" + }, + { + "text": ";", + "kind": "punctuation" + }, + { + "text": " ", + "kind": "space" + }, + { + "text": "}", + "kind": "punctuation" + }, + { + "text": "[", + "kind": "punctuation" + }, + { + "text": "Keys", + "kind": "typeParameterName" + }, + { + "text": "]", + "kind": "punctuation" + } + ], + "documentation": [ + { + "text": "Type instantiated to perform partial inferences from indexed accesses", + "kind": "text" + } + ] + }, { "name": "Pick", "kind": "type", diff --git a/tests/baselines/reference/correlatedUnions.types b/tests/baselines/reference/correlatedUnions.types index 82f0b9d082942..ab2fe4d37b713 100644 --- a/tests/baselines/reference/correlatedUnions.types +++ b/tests/baselines/reference/correlatedUnions.types @@ -1,8 +1,5 @@ //// [tests/cases/compiler/correlatedUnions.ts] //// -=== Performance Stats === -Type Count: 1,000 - === correlatedUnions.ts === // Various repros from #30581 @@ -775,8 +772,8 @@ function ff1() { > : ^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^ const funs: { [P in Keys]: (...args: ArgMap[P]) => void } = { ->funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>funs : { sum: (a: number, b: number) => void; concat: (a: string, b: string, c: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ >args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[P] > : ^^^^^^^ ^^^^^^^^^^ ^^^^^^ >{ sum: (a, b) => a + b, concat: (a, b, c) => a + b + c } : { sum: (a: number, b: number) => number; concat: (a: string, b: string, c: string) => string; } @@ -829,20 +826,20 @@ function ff1() { > : ^^^^^^^ ^^^^^^^^^^ ^^^^^^ const fn = funs[funKey]; ->fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ->funs[funKey] : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ ->funs : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; } -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>fn : { sum: (a: number, b: number) => void; concat: (a: string, b: string, c: string) => void; }[K] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ +>funs[funKey] : { sum: (a: number, b: number) => void; concat: (a: string, b: string, c: string) => void; }[K] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ +>funs : { sum: (a: number, b: number) => void; concat: (a: string, b: string, c: string) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ >funKey : K > : ^ fn(...args); >fn(...args) : void > : ^^^^ ->fn : { concat: (a: string, b: string, c: string) => void; sum: (a: number, b: number) => void; }[K] -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ +>fn : { sum: (a: number, b: number) => void; concat: (a: string, b: string, c: string) => void; }[K] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^ >...args : string | number > : ^^^^^^^^^^^^^^^ >args : { sum: [a: number, b: number]; concat: [a: string, b: string, c: string]; }[K] diff --git a/tests/baselines/reference/dependentDestructuredVariables.types b/tests/baselines/reference/dependentDestructuredVariables.types index 1b829f101d426..ef798f07a45a7 100644 --- a/tests/baselines/reference/dependentDestructuredVariables.types +++ b/tests/baselines/reference/dependentDestructuredVariables.types @@ -2,7 +2,7 @@ === Performance Stats === Type Count: 2,500 -Instantiation count: 5,000 +Instantiation count: 2,500 -> 5,000 === dependentDestructuredVariables.ts === type Action = diff --git a/tests/baselines/reference/indexAccessCombinedInference.js b/tests/baselines/reference/indexAccessCombinedInference.js new file mode 100644 index 0000000000000..27fda26376c72 --- /dev/null +++ b/tests/baselines/reference/indexAccessCombinedInference.js @@ -0,0 +1,150 @@ +//// [tests/cases/compiler/indexAccessCombinedInference.ts] //// + +//// [indexAccessCombinedInference.ts] +// Simple case +interface Args { + TA: object, + TY: object +} + +declare function foo( + a: T["TA"], + b: T["TY"]): T["TA"] & T["TY"]; + +const x = foo({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); + +// Union result type +interface A { + foo: number; +} +interface B { + bar: string; +} +declare const something: A | B; + +const y = foo(something, { bat: 42 }); + +// Union key type +interface Args2 { + TA?: object, // Optional since only one of TA or TB needs to be infered in the below argument list + TB?: object, + TY: object +} +declare function foo2( + a: T["TA"] | T["TB"], + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +declare function foo3( // Morally equivalent to foo2 + a: T["TA" | "TB"], + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +let z = foo2({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +let zz = foo3({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +z = zz; +zz = z; + +// Higher-order +interface Args3 { + Key: "A" | "B", + A: object, + B: object, + Merge: object, +} +declare const either: "A" | "B"; +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; + +const opt1 = pickOne("A", {x: 12}, {y: ""}, {z: /./}); +const opt2 = pickOne("B", {x: 12}, {y: ""}, {z: /./}); +const opt3 = pickOne(either, {x: 12}, {y: ""}, {z: /./}); + +const pickDelayed = (x: TKey) => pickOne(x, {j: x}, {i: x}, {chosen: x}); +const opt4 = pickDelayed("A"); +const opt5 = pickDelayed("B"); +const opt6 = pickDelayed(either); + +// Reopenable +interface Args3 { + /** + * One must make patched parameters optional, otherwise signatures expecting the unpatched + * interface (ie, pickOne above) will not be able to produce a type satisfying the interface + * (as there are no inference sites for the new members) and will fall back to the constraints on each member + */ + Extra?: object, +} +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & {into: T["Merge"], extra: T["Extra"]}; +const opt7 = pickOne("A", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +const opt8 = pickOne("B", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +const opt9 = pickOne(either, {x: 12}, {y: ""}, {z: /./}, {z: /./}); + +// Interactions with `this` types +interface TPicker { + Key: keyof this, + X: number, + Y: string +} +declare function chooseLiteral(choice: T["Key"], x: T["X"], y:T["Y"]): T[T["Key"]]; +const cx = chooseLiteral("X", 1, "no"); +const cy = chooseLiteral("Y", 0, "yes"); +const ceither = chooseLiteral("X" as "X" | "Y", 1, "yes"); +const cneither = chooseLiteral("Key", 0, "no"); + +// Multiple inference sites +interface Args4 { + 0: object, + 1: Record, +} +declare function dualInputs(x: T[0], y: T[0], toDelay: T[1]): T[0] & {transformers: T[1]}; + +const result = dualInputs({x: 0}, {x: 1}, {x: () => ""}); + + +//// [indexAccessCombinedInference.js] +var x = foo({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +var y = foo(something, { bat: 42 }); +var z = foo2({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +var zz = foo3({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +z = zz; +zz = z; +var opt1 = pickOne("A", { x: 12 }, { y: "" }, { z: /./ }); +var opt2 = pickOne("B", { x: 12 }, { y: "" }, { z: /./ }); +var opt3 = pickOne(either, { x: 12 }, { y: "" }, { z: /./ }); +var pickDelayed = function (x) { return pickOne(x, { j: x }, { i: x }, { chosen: x }); }; +var opt4 = pickDelayed("A"); +var opt5 = pickDelayed("B"); +var opt6 = pickDelayed(either); +var opt7 = pickOne("A", { x: 12 }, { y: "" }, { z: /./ }, { z: /./ }); +var opt8 = pickOne("B", { x: 12 }, { y: "" }, { z: /./ }, { z: /./ }); +var opt9 = pickOne(either, { x: 12 }, { y: "" }, { z: /./ }, { z: /./ }); +var cx = chooseLiteral("X", 1, "no"); +var cy = chooseLiteral("Y", 0, "yes"); +var ceither = chooseLiteral("X", 1, "yes"); +var cneither = chooseLiteral("Key", 0, "no"); +var result = dualInputs({ x: 0 }, { x: 1 }, { x: function () { return ""; } }); diff --git a/tests/baselines/reference/indexAccessCombinedInference.symbols b/tests/baselines/reference/indexAccessCombinedInference.symbols new file mode 100644 index 0000000000000..cf2b85572c454 --- /dev/null +++ b/tests/baselines/reference/indexAccessCombinedInference.symbols @@ -0,0 +1,377 @@ +//// [tests/cases/compiler/indexAccessCombinedInference.ts] //// + +=== indexAccessCombinedInference.ts === +// Simple case +interface Args { +>Args : Symbol(Args, Decl(indexAccessCombinedInference.ts, 0, 0)) + + TA: object, +>TA : Symbol(Args.TA, Decl(indexAccessCombinedInference.ts, 1, 16)) + + TY: object +>TY : Symbol(Args.TY, Decl(indexAccessCombinedInference.ts, 2, 15)) +} + +declare function foo( +>foo : Symbol(foo, Decl(indexAccessCombinedInference.ts, 4, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 6, 21)) +>Args : Symbol(Args, Decl(indexAccessCombinedInference.ts, 0, 0)) + + a: T["TA"], +>a : Symbol(a, Decl(indexAccessCombinedInference.ts, 6, 37)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 6, 21)) + + b: T["TY"]): T["TA"] & T["TY"]; +>b : Symbol(b, Decl(indexAccessCombinedInference.ts, 7, 15)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 6, 21)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 6, 21)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 6, 21)) + +const x = foo({ +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 10, 5)) +>foo : Symbol(foo, Decl(indexAccessCombinedInference.ts, 4, 1)) + + x: { +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 10, 15)) + + j: 12, +>j : Symbol(j, Decl(indexAccessCombinedInference.ts, 11, 8)) + + i: 11 +>i : Symbol(i, Decl(indexAccessCombinedInference.ts, 12, 14)) + } +}, { y: 42 }); +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 15, 4)) + +// Union result type +interface A { +>A : Symbol(A, Decl(indexAccessCombinedInference.ts, 15, 14)) + + foo: number; +>foo : Symbol(A.foo, Decl(indexAccessCombinedInference.ts, 18, 13)) +} +interface B { +>B : Symbol(B, Decl(indexAccessCombinedInference.ts, 20, 1)) + + bar: string; +>bar : Symbol(B.bar, Decl(indexAccessCombinedInference.ts, 21, 13)) +} +declare const something: A | B; +>something : Symbol(something, Decl(indexAccessCombinedInference.ts, 24, 13)) +>A : Symbol(A, Decl(indexAccessCombinedInference.ts, 15, 14)) +>B : Symbol(B, Decl(indexAccessCombinedInference.ts, 20, 1)) + +const y = foo(something, { bat: 42 }); +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 26, 5)) +>foo : Symbol(foo, Decl(indexAccessCombinedInference.ts, 4, 1)) +>something : Symbol(something, Decl(indexAccessCombinedInference.ts, 24, 13)) +>bat : Symbol(bat, Decl(indexAccessCombinedInference.ts, 26, 26)) + +// Union key type +interface Args2 { +>Args2 : Symbol(Args2, Decl(indexAccessCombinedInference.ts, 26, 38)) + + TA?: object, // Optional since only one of TA or TB needs to be infered in the below argument list +>TA : Symbol(Args2.TA, Decl(indexAccessCombinedInference.ts, 29, 17)) + + TB?: object, +>TB : Symbol(Args2.TB, Decl(indexAccessCombinedInference.ts, 30, 16)) + + TY: object +>TY : Symbol(Args2.TY, Decl(indexAccessCombinedInference.ts, 31, 16)) +} +declare function foo2( +>foo2 : Symbol(foo2, Decl(indexAccessCombinedInference.ts, 33, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) +>Args2 : Symbol(Args2, Decl(indexAccessCombinedInference.ts, 26, 38)) + + a: T["TA"] | T["TB"], +>a : Symbol(a, Decl(indexAccessCombinedInference.ts, 34, 39)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) + + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +>b : Symbol(b, Decl(indexAccessCombinedInference.ts, 35, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) +>a : Symbol(a, Decl(indexAccessCombinedInference.ts, 36, 18)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) +>b : Symbol(b, Decl(indexAccessCombinedInference.ts, 36, 29)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 34, 22)) + +declare function foo3( // Morally equivalent to foo2 +>foo3 : Symbol(foo3, Decl(indexAccessCombinedInference.ts, 36, 52)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) +>Args2 : Symbol(Args2, Decl(indexAccessCombinedInference.ts, 26, 38)) + + a: T["TA" | "TB"], +>a : Symbol(a, Decl(indexAccessCombinedInference.ts, 37, 39)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) + + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +>b : Symbol(b, Decl(indexAccessCombinedInference.ts, 38, 22)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) +>a : Symbol(a, Decl(indexAccessCombinedInference.ts, 39, 18)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) +>b : Symbol(b, Decl(indexAccessCombinedInference.ts, 39, 29)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 37, 22)) + +let z = foo2({ +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 40, 3)) +>foo2 : Symbol(foo2, Decl(indexAccessCombinedInference.ts, 33, 1)) + + x: { +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 40, 14)) + + j: 12, +>j : Symbol(j, Decl(indexAccessCombinedInference.ts, 41, 8)) + + i: 11 +>i : Symbol(i, Decl(indexAccessCombinedInference.ts, 42, 14)) + } +}, { y: 42 }); +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 45, 4)) + +let zz = foo3({ +>zz : Symbol(zz, Decl(indexAccessCombinedInference.ts, 46, 3)) +>foo3 : Symbol(foo3, Decl(indexAccessCombinedInference.ts, 36, 52)) + + x: { +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 46, 15)) + + j: 12, +>j : Symbol(j, Decl(indexAccessCombinedInference.ts, 47, 8)) + + i: 11 +>i : Symbol(i, Decl(indexAccessCombinedInference.ts, 48, 14)) + } +}, { y: 42 }); +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 51, 4)) + +z = zz; +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 40, 3)) +>zz : Symbol(zz, Decl(indexAccessCombinedInference.ts, 46, 3)) + +zz = z; +>zz : Symbol(zz, Decl(indexAccessCombinedInference.ts, 46, 3)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 40, 3)) + +// Higher-order +interface Args3 { +>Args3 : Symbol(Args3, Decl(indexAccessCombinedInference.ts, 53, 7), Decl(indexAccessCombinedInference.ts, 72, 33)) + + Key: "A" | "B", +>Key : Symbol(Args3.Key, Decl(indexAccessCombinedInference.ts, 56, 17)) + + A: object, +>A : Symbol(Args3.A, Decl(indexAccessCombinedInference.ts, 57, 19)) + + B: object, +>B : Symbol(Args3.B, Decl(indexAccessCombinedInference.ts, 58, 14)) + + Merge: object, +>Merge : Symbol(Args3.Merge, Decl(indexAccessCombinedInference.ts, 59, 14)) +} +declare const either: "A" | "B"; +>either : Symbol(either, Decl(indexAccessCombinedInference.ts, 62, 13)) + +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>Args3 : Symbol(Args3, Decl(indexAccessCombinedInference.ts, 53, 7), Decl(indexAccessCombinedInference.ts, 72, 33)) +>key : Symbol(key, Decl(indexAccessCombinedInference.ts, 63, 42)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>left : Symbol(left, Decl(indexAccessCombinedInference.ts, 63, 56)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>right : Symbol(right, Decl(indexAccessCombinedInference.ts, 63, 70)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>into : Symbol(into, Decl(indexAccessCombinedInference.ts, 63, 85)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 63, 25)) + +const opt1 = pickOne("A", {x: 12}, {y: ""}, {z: /./}); +>opt1 : Symbol(opt1, Decl(indexAccessCombinedInference.ts, 65, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 65, 27)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 65, 36)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 65, 45)) + +const opt2 = pickOne("B", {x: 12}, {y: ""}, {z: /./}); +>opt2 : Symbol(opt2, Decl(indexAccessCombinedInference.ts, 66, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 66, 27)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 66, 36)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 66, 45)) + +const opt3 = pickOne(either, {x: 12}, {y: ""}, {z: /./}); +>opt3 : Symbol(opt3, Decl(indexAccessCombinedInference.ts, 67, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>either : Symbol(either, Decl(indexAccessCombinedInference.ts, 62, 13)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 67, 30)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 67, 39)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 67, 48)) + +const pickDelayed = (x: TKey) => pickOne(x, {j: x}, {i: x}, {chosen: x}); +>pickDelayed : Symbol(pickDelayed, Decl(indexAccessCombinedInference.ts, 69, 5)) +>TKey : Symbol(TKey, Decl(indexAccessCombinedInference.ts, 69, 21)) +>Args3 : Symbol(Args3, Decl(indexAccessCombinedInference.ts, 53, 7), Decl(indexAccessCombinedInference.ts, 72, 33)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 69, 48)) +>TKey : Symbol(TKey, Decl(indexAccessCombinedInference.ts, 69, 21)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 69, 48)) +>j : Symbol(j, Decl(indexAccessCombinedInference.ts, 69, 72)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 69, 48)) +>i : Symbol(i, Decl(indexAccessCombinedInference.ts, 69, 80)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 69, 48)) +>chosen : Symbol(chosen, Decl(indexAccessCombinedInference.ts, 69, 88)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 69, 48)) + +const opt4 = pickDelayed("A"); +>opt4 : Symbol(opt4, Decl(indexAccessCombinedInference.ts, 70, 5)) +>pickDelayed : Symbol(pickDelayed, Decl(indexAccessCombinedInference.ts, 69, 5)) + +const opt5 = pickDelayed("B"); +>opt5 : Symbol(opt5, Decl(indexAccessCombinedInference.ts, 71, 5)) +>pickDelayed : Symbol(pickDelayed, Decl(indexAccessCombinedInference.ts, 69, 5)) + +const opt6 = pickDelayed(either); +>opt6 : Symbol(opt6, Decl(indexAccessCombinedInference.ts, 72, 5)) +>pickDelayed : Symbol(pickDelayed, Decl(indexAccessCombinedInference.ts, 69, 5)) +>either : Symbol(either, Decl(indexAccessCombinedInference.ts, 62, 13)) + +// Reopenable +interface Args3 { +>Args3 : Symbol(Args3, Decl(indexAccessCombinedInference.ts, 53, 7), Decl(indexAccessCombinedInference.ts, 72, 33)) + + /** + * One must make patched parameters optional, otherwise signatures expecting the unpatched + * interface (ie, pickOne above) will not be able to produce a type satisfying the interface + * (as there are no inference sites for the new members) and will fall back to the constraints on each member + */ + Extra?: object, +>Extra : Symbol(Args3.Extra, Decl(indexAccessCombinedInference.ts, 75, 17)) +} +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & {into: T["Merge"], extra: T["Extra"]}; +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>Args3 : Symbol(Args3, Decl(indexAccessCombinedInference.ts, 53, 7), Decl(indexAccessCombinedInference.ts, 72, 33)) +>key : Symbol(key, Decl(indexAccessCombinedInference.ts, 83, 42)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>left : Symbol(left, Decl(indexAccessCombinedInference.ts, 83, 56)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>right : Symbol(right, Decl(indexAccessCombinedInference.ts, 83, 70)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>into : Symbol(into, Decl(indexAccessCombinedInference.ts, 83, 85)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>extra : Symbol(extra, Decl(indexAccessCombinedInference.ts, 83, 103)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>into : Symbol(into, Decl(indexAccessCombinedInference.ts, 83, 139)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) +>extra : Symbol(extra, Decl(indexAccessCombinedInference.ts, 83, 156)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 83, 25)) + +const opt7 = pickOne("A", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt7 : Symbol(opt7, Decl(indexAccessCombinedInference.ts, 84, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 84, 27)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 84, 36)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 84, 45)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 84, 55)) + +const opt8 = pickOne("B", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt8 : Symbol(opt8, Decl(indexAccessCombinedInference.ts, 85, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 85, 27)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 85, 36)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 85, 45)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 85, 55)) + +const opt9 = pickOne(either, {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt9 : Symbol(opt9, Decl(indexAccessCombinedInference.ts, 86, 5)) +>pickOne : Symbol(pickOne, Decl(indexAccessCombinedInference.ts, 62, 32), Decl(indexAccessCombinedInference.ts, 82, 1)) +>either : Symbol(either, Decl(indexAccessCombinedInference.ts, 62, 13)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 86, 30)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 86, 39)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 86, 48)) +>z : Symbol(z, Decl(indexAccessCombinedInference.ts, 86, 58)) + +// Interactions with `this` types +interface TPicker { +>TPicker : Symbol(TPicker, Decl(indexAccessCombinedInference.ts, 86, 67)) + + Key: keyof this, +>Key : Symbol(TPicker.Key, Decl(indexAccessCombinedInference.ts, 89, 19)) + + X: number, +>X : Symbol(TPicker.X, Decl(indexAccessCombinedInference.ts, 90, 20)) + + Y: string +>Y : Symbol(TPicker.Y, Decl(indexAccessCombinedInference.ts, 91, 14)) +} +declare function chooseLiteral(choice: T["Key"], x: T["X"], y:T["Y"]): T[T["Key"]]; +>chooseLiteral : Symbol(chooseLiteral, Decl(indexAccessCombinedInference.ts, 93, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) +>TPicker : Symbol(TPicker, Decl(indexAccessCombinedInference.ts, 86, 67)) +>choice : Symbol(choice, Decl(indexAccessCombinedInference.ts, 94, 50)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 94, 67)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 94, 78)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 94, 31)) + +const cx = chooseLiteral("X", 1, "no"); +>cx : Symbol(cx, Decl(indexAccessCombinedInference.ts, 95, 5)) +>chooseLiteral : Symbol(chooseLiteral, Decl(indexAccessCombinedInference.ts, 93, 1)) + +const cy = chooseLiteral("Y", 0, "yes"); +>cy : Symbol(cy, Decl(indexAccessCombinedInference.ts, 96, 5)) +>chooseLiteral : Symbol(chooseLiteral, Decl(indexAccessCombinedInference.ts, 93, 1)) + +const ceither = chooseLiteral("X" as "X" | "Y", 1, "yes"); +>ceither : Symbol(ceither, Decl(indexAccessCombinedInference.ts, 97, 5)) +>chooseLiteral : Symbol(chooseLiteral, Decl(indexAccessCombinedInference.ts, 93, 1)) + +const cneither = chooseLiteral("Key", 0, "no"); +>cneither : Symbol(cneither, Decl(indexAccessCombinedInference.ts, 98, 5)) +>chooseLiteral : Symbol(chooseLiteral, Decl(indexAccessCombinedInference.ts, 93, 1)) + +// Multiple inference sites +interface Args4 { +>Args4 : Symbol(Args4, Decl(indexAccessCombinedInference.ts, 98, 47)) + + 0: object, +>0 : Symbol(Args4[0], Decl(indexAccessCombinedInference.ts, 101, 17)) + + 1: Record, +>1 : Symbol(Args4[1], Decl(indexAccessCombinedInference.ts, 102, 14)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} +declare function dualInputs(x: T[0], y: T[0], toDelay: T[1]): T[0] & {transformers: T[1]}; +>dualInputs : Symbol(dualInputs, Decl(indexAccessCombinedInference.ts, 104, 1)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) +>Args4 : Symbol(Args4, Decl(indexAccessCombinedInference.ts, 98, 47)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 105, 45)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) +>y : Symbol(y, Decl(indexAccessCombinedInference.ts, 105, 53)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) +>toDelay : Symbol(toDelay, Decl(indexAccessCombinedInference.ts, 105, 62)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) +>transformers : Symbol(transformers, Decl(indexAccessCombinedInference.ts, 105, 87)) +>T : Symbol(T, Decl(indexAccessCombinedInference.ts, 105, 28)) + +const result = dualInputs({x: 0}, {x: 1}, {x: () => ""}); +>result : Symbol(result, Decl(indexAccessCombinedInference.ts, 107, 5)) +>dualInputs : Symbol(dualInputs, Decl(indexAccessCombinedInference.ts, 104, 1)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 107, 27)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 107, 35)) +>x : Symbol(x, Decl(indexAccessCombinedInference.ts, 107, 43)) + diff --git a/tests/baselines/reference/indexAccessCombinedInference.types b/tests/baselines/reference/indexAccessCombinedInference.types new file mode 100644 index 0000000000000..0794d5b9689e7 --- /dev/null +++ b/tests/baselines/reference/indexAccessCombinedInference.types @@ -0,0 +1,670 @@ +//// [tests/cases/compiler/indexAccessCombinedInference.ts] //// + +=== indexAccessCombinedInference.ts === +// Simple case +interface Args { + TA: object, +>TA : object +> : ^^^^^^ + + TY: object +>TY : object +> : ^^^^^^ +} + +declare function foo( +>foo : (a: T["TA"], b: T["TY"]) => T["TA"] & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ + + a: T["TA"], +>a : T["TA"] +> : ^^^^^^^ + + b: T["TY"]): T["TA"] & T["TY"]; +>b : T["TY"] +> : ^^^^^^^ + +const x = foo({ +>x : { x: { j: number; i: number; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo({ x: { j: 12, i: 11 }}, { y: 42 }) : { x: { j: number; i: number; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : (a: T["TA"], b: T["TY"]) => T["TA"] & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>{ x: { j: 12, i: 11 }} : { x: { j: number; i: number; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: { +>x : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ j: 12, i: 11 } : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + + j: 12, +>j : number +> : ^^^^^^ +>12 : 12 +> : ^^ + + i: 11 +>i : number +> : ^^^^^^ +>11 : 11 +> : ^^ + } +}, { y: 42 }); +>{ y: 42 } : { y: number; } +> : ^^^^^^^^^^^^^^ +>y : number +> : ^^^^^^ +>42 : 42 +> : ^^ + +// Union result type +interface A { + foo: number; +>foo : number +> : ^^^^^^ +} +interface B { + bar: string; +>bar : string +> : ^^^^^^ +} +declare const something: A | B; +>something : A | B +> : ^^^^^ + +const y = foo(something, { bat: 42 }); +>y : (A & { bat: number; }) | (B & { bat: number; }) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo(something, { bat: 42 }) : (A | B) & { bat: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : (a: T["TA"], b: T["TY"]) => T["TA"] & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>something : A | B +> : ^^^^^ +>{ bat: 42 } : { bat: number; } +> : ^^^^^^^^^^^^^^^^ +>bat : number +> : ^^^^^^ +>42 : 42 +> : ^^ + +// Union key type +interface Args2 { + TA?: object, // Optional since only one of TA or TB needs to be infered in the below argument list +>TA : object +> : ^^^^^^ + + TB?: object, +>TB : object +> : ^^^^^^ + + TY: object +>TY : object +> : ^^^^^^ +} +declare function foo2( +>foo2 : (a: T["TA"] | T["TB"], b: T["TY"]) => { a: T["TA"]; b: T["TB"]; } & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ + + a: T["TA"] | T["TB"], +>a : T["TA"] | T["TB"] +> : ^^^^^^^^^^^^^^^^^ + + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +>b : T["TY"] +> : ^^^^^^^ +>a : T["TA"] +> : ^^^^^^^ +>b : T["TB"] +> : ^^^^^^^ + +declare function foo3( // Morally equivalent to foo2 +>foo3 : (a: T["TA" | "TB"], b: T["TY"]) => { a: T["TA"]; b: T["TB"]; } & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ + + a: T["TA" | "TB"], +>a : T["TA" | "TB"] +> : ^^^^^^^^^^^^^^ + + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +>b : T["TY"] +> : ^^^^^^^ +>a : T["TA"] +> : ^^^^^^^ +>b : T["TB"] +> : ^^^^^^^ + +let z = foo2({ +>z : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo2({ x: { j: 12, i: 11 }}, { y: 42 }) : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo2 : (a: T["TA"] | T["TB"], b: T["TY"]) => { a: T["TA"]; b: T["TB"]; } & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>{ x: { j: 12, i: 11 }} : { x: { j: number; i: number; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: { +>x : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ j: 12, i: 11 } : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + + j: 12, +>j : number +> : ^^^^^^ +>12 : 12 +> : ^^ + + i: 11 +>i : number +> : ^^^^^^ +>11 : 11 +> : ^^ + } +}, { y: 42 }); +>{ y: 42 } : { y: number; } +> : ^^^^^^^^^^^^^^ +>y : number +> : ^^^^^^ +>42 : 42 +> : ^^ + +let zz = foo3({ +>zz : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo3({ x: { j: 12, i: 11 }}, { y: 42 }) : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo3 : (a: T["TA" | "TB"], b: T["TY"]) => { a: T["TA"]; b: T["TB"]; } & T["TY"] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>{ x: { j: 12, i: 11 }} : { x: { j: number; i: number; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: { +>x : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ j: 12, i: 11 } : { j: number; i: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + + j: 12, +>j : number +> : ^^^^^^ +>12 : 12 +> : ^^ + + i: 11 +>i : number +> : ^^^^^^ +>11 : 11 +> : ^^ + } +}, { y: 42 }); +>{ y: 42 } : { y: number; } +> : ^^^^^^^^^^^^^^ +>y : number +> : ^^^^^^ +>42 : 42 +> : ^^ + +z = zz; +>z = zz : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>z : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>zz : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +zz = z; +>zz = z : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>zz : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>z : { a: { x: { j: number; i: number; }; }; b: { x: { j: number; i: number; }; }; } & { y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +// Higher-order +interface Args3 { + Key: "A" | "B", +>Key : "A" | "B" +> : ^^^^^^^^^ + + A: object, +>A : object +> : ^^^^^^ + + B: object, +>B : object +> : ^^^^^^ + + Merge: object, +>Merge : object +> : ^^^^^^ +} +declare const either: "A" | "B"; +>either : "A" | "B" +> : ^^^^^^^^^ + +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T_1["Key"], left: T_1["A"], right: T_1["B"], into: T_1["Merge"], extra: T_1["Extra"]): T_1[T_1["Key"]] & { into: T_1["Merge"]; extra: T_1["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>key : T["Key"] +> : ^^^^^^^^ +>left : T["A"] +> : ^^^^^^ +>right : T["B"] +> : ^^^^^^ +>into : T["Merge"] +> : ^^^^^^^^^^ + +const opt1 = pickOne("A", {x: 12}, {y: ""}, {z: /./}); +>opt1 : { x: number; } & { z: RegExp; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne("A", {x: 12}, {y: ""}, {z: /./}) : { x: number; } & { z: RegExp; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>"A" : "A" +> : ^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +const opt2 = pickOne("B", {x: 12}, {y: ""}, {z: /./}); +>opt2 : { y: string; } & { z: RegExp; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne("B", {x: 12}, {y: ""}, {z: /./}) : { y: string; } & { z: RegExp; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>"B" : "B" +> : ^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +const opt3 = pickOne(either, {x: 12}, {y: ""}, {z: /./}); +>opt3 : ({ x: number; } & { z: RegExp; }) | ({ y: string; } & { z: RegExp; }) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne(either, {x: 12}, {y: ""}, {z: /./}) : ({ x: number; } | { y: string; }) & { z: RegExp; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>either : "A" | "B" +> : ^^^^^^^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +const pickDelayed = (x: TKey) => pickOne(x, {j: x}, {i: x}, {chosen: x}); +>pickDelayed : (x: TKey) => ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(x: TKey) => pickOne(x, {j: x}, {i: x}, {chosen: x}) : (x: TKey) => ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>x : TKey +> : ^^^^ +>pickOne(x, {j: x}, {i: x}, {chosen: x}) : ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>x : TKey +> : ^^^^ +>{j: x} : { j: TKey; } +> : ^^^^^^^^^^^^ +>j : TKey +> : ^^^^ +>x : TKey +> : ^^^^ +>{i: x} : { i: TKey; } +> : ^^^^^^^^^^^^ +>i : TKey +> : ^^^^ +>x : TKey +> : ^^^^ +>{chosen: x} : { chosen: TKey; } +> : ^^^^^^^^^^^^^^^^^ +>chosen : TKey +> : ^^^^ +>x : TKey +> : ^^^^ + +const opt4 = pickDelayed("A"); +>opt4 : { j: "A"; } & { chosen: "A"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed("A") : { j: "A"; } & { chosen: "A"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed : (x: TKey) => ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"A" : "A" +> : ^^^ + +const opt5 = pickDelayed("B"); +>opt5 : { i: "B"; } & { chosen: "B"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed("B") : { i: "B"; } & { chosen: "B"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed : (x: TKey) => ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"B" : "B" +> : ^^^ + +const opt6 = pickDelayed(either); +>opt6 : ({ j: "A" | "B"; } & { chosen: "A" | "B"; }) | ({ i: "A" | "B"; } & { chosen: "A" | "B"; }) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed(either) : ({ j: "A" | "B"; } | { i: "A" | "B"; }) & { chosen: "A" | "B"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickDelayed : (x: TKey) => ({ Key: TKey; } & { A: { j: TKey; }; } & { B: { i: TKey; }; } & { Merge: { chosen: TKey; }; })[TKey] & { chosen: TKey; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>either : "A" | "B" +> : ^^^^^^^^^ + +// Reopenable +interface Args3 { + /** + * One must make patched parameters optional, otherwise signatures expecting the unpatched + * interface (ie, pickOne above) will not be able to produce a type satisfying the interface + * (as there are no inference sites for the new members) and will fall back to the constraints on each member + */ + Extra?: object, +>Extra : object +> : ^^^^^^ +} +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & {into: T["Merge"], extra: T["Extra"]}; +>pickOne : { (key: T_1["Key"], left: T_1["A"], right: T_1["B"], into: T_1["Merge"]): T_1[T_1["Key"]] & T_1["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>key : T["Key"] +> : ^^^^^^^^ +>left : T["A"] +> : ^^^^^^ +>right : T["B"] +> : ^^^^^^ +>into : T["Merge"] +> : ^^^^^^^^^^ +>extra : T["Extra"] +> : ^^^^^^^^^^ +>into : T["Merge"] +> : ^^^^^^^^^^ +>extra : T["Extra"] +> : ^^^^^^^^^^ + +const opt7 = pickOne("A", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt7 : { x: number; } & { into: { z: RegExp; }; extra: { z: RegExp; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne("A", {x: 12}, {y: ""}, {z: /./}, {z: /./}) : { x: number; } & { into: { z: RegExp; }; extra: { z: RegExp; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>"A" : "A" +> : ^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +const opt8 = pickOne("B", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt8 : { y: string; } & { into: { z: RegExp; }; extra: { z: RegExp; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne("B", {x: 12}, {y: ""}, {z: /./}, {z: /./}) : { y: string; } & { into: { z: RegExp; }; extra: { z: RegExp; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>"B" : "B" +> : ^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +const opt9 = pickOne(either, {x: 12}, {y: ""}, {z: /./}, {z: /./}); +>opt9 : ({ x: number; } & { into: { z: RegExp; }; extra: { z: RegExp; }; }) | ({ y: string; } & { into: { z: RegExp; }; extra: { z: RegExp; }; }) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne(either, {x: 12}, {y: ""}, {z: /./}, {z: /./}) : ({ x: number; } | { y: string; }) & { into: { z: RegExp; }; extra: { z: RegExp; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>pickOne : { (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; (key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & { into: T["Merge"]; extra: T["Extra"]; }; } +> : ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>either : "A" | "B" +> : ^^^^^^^^^ +>{x: 12} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>12 : 12 +> : ^^ +>{y: ""} : { y: string; } +> : ^^^^^^^^^^^^^^ +>y : string +> : ^^^^^^ +>"" : "" +> : ^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ +>{z: /./} : { z: RegExp; } +> : ^^^^^^^^^^^^^^ +>z : RegExp +> : ^^^^^^ +>/./ : RegExp +> : ^^^^^^ + +// Interactions with `this` types +interface TPicker { + Key: keyof this, +>Key : keyof this +> : ^^^^^^^^^^ + + X: number, +>X : number +> : ^^^^^^ + + Y: string +>Y : string +> : ^^^^^^ +} +declare function chooseLiteral(choice: T["Key"], x: T["X"], y:T["Y"]): T[T["Key"]]; +>chooseLiteral : (choice: T["Key"], x: T["X"], y: T["Y"]) => T[T["Key"]] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>choice : T["Key"] +> : ^^^^^^^^ +>x : T["X"] +> : ^^^^^^ +>y : T["Y"] +> : ^^^^^^ + +const cx = chooseLiteral("X", 1, "no"); +>cx : 1 +> : ^ +>chooseLiteral("X", 1, "no") : 1 +> : ^ +>chooseLiteral : (choice: T["Key"], x: T["X"], y: T["Y"]) => T[T["Key"]] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>"X" : "X" +> : ^^^ +>1 : 1 +> : ^ +>"no" : "no" +> : ^^^^ + +const cy = chooseLiteral("Y", 0, "yes"); +>cy : "yes" +> : ^^^^^ +>chooseLiteral("Y", 0, "yes") : "yes" +> : ^^^^^ +>chooseLiteral : (choice: T["Key"], x: T["X"], y: T["Y"]) => T[T["Key"]] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>"Y" : "Y" +> : ^^^ +>0 : 0 +> : ^ +>"yes" : "yes" +> : ^^^^^ + +const ceither = chooseLiteral("X" as "X" | "Y", 1, "yes"); +>ceither : 1 | "yes" +> : ^^^^^^^^^ +>chooseLiteral("X" as "X" | "Y", 1, "yes") : 1 | "yes" +> : ^^^^^^^^^ +>chooseLiteral : (choice: T["Key"], x: T["X"], y: T["Y"]) => T[T["Key"]] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>"X" as "X" | "Y" : "X" | "Y" +> : ^^^^^^^^^ +>"X" : "X" +> : ^^^ +>1 : 1 +> : ^ +>"yes" : "yes" +> : ^^^^^ + +const cneither = chooseLiteral("Key", 0, "no"); +>cneither : "Key" +> : ^^^^^ +>chooseLiteral("Key", 0, "no") : "Key" +> : ^^^^^ +>chooseLiteral : (choice: T["Key"], x: T["X"], y: T["Y"]) => T[T["Key"]] +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>"Key" : "Key" +> : ^^^^^ +>0 : 0 +> : ^ +>"no" : "no" +> : ^^^^ + +// Multiple inference sites +interface Args4 { + 0: object, +>0 : object +> : ^^^^^^ + + 1: Record, +>1 : Record +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} +declare function dualInputs(x: T[0], y: T[0], toDelay: T[1]): T[0] & {transformers: T[1]}; +>dualInputs : (x: T[0], y: T[0], toDelay: T[1]) => T[0] & { transformers: T[1]; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>x : T[0] +> : ^^^^ +>y : T[0] +> : ^^^^ +>toDelay : T[1] +> : ^^^^ +>transformers : T[1] +> : ^^^^ + +const result = dualInputs({x: 0}, {x: 1}, {x: () => ""}); +>result : { x: number; } & { x: number; } & { transformers: { x: () => ""; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>dualInputs({x: 0}, {x: 1}, {x: () => ""}) : { x: number; } & { x: number; } & { transformers: { x: () => ""; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>dualInputs : (x: T[0], y: T[0], toDelay: T[1]) => T[0] & { transformers: T[1]; } +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>{x: 0} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>0 : 0 +> : ^ +>{x: 1} : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>1 : 1 +> : ^ +>{x: () => ""} : { x: () => ""; } +> : ^^^^^^^^^^^^^^^^ +>x : () => "" +> : ^^^^^^^^ +>() => "" : () => "" +> : ^^^^^^^^ +>"" : "" +> : ^^ + diff --git a/tests/baselines/reference/inferingFromAny.types b/tests/baselines/reference/inferingFromAny.types index daf6f2ff8bf33..a959f6dc9557a 100644 --- a/tests/baselines/reference/inferingFromAny.types +++ b/tests/baselines/reference/inferingFromAny.types @@ -279,7 +279,8 @@ var a = f18(a); var a = f19(a, a); >a : any ->f19(a, a) : any +>f19(a, a) : { [x: string]: any; } +> : ^^^^^^^^^^^^^^^^^^^^^ >f19 : (k: K, x: T[K]) => T > : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ >a : any diff --git a/tests/baselines/reference/nonnullAssertionPropegatesContextualType.types b/tests/baselines/reference/nonnullAssertionPropegatesContextualType.types index 8424e057fb0ad..59010f1f05e57 100644 --- a/tests/baselines/reference/nonnullAssertionPropegatesContextualType.types +++ b/tests/baselines/reference/nonnullAssertionPropegatesContextualType.types @@ -1,8 +1,5 @@ //// [tests/cases/compiler/nonnullAssertionPropegatesContextualType.ts] //// -=== Performance Stats === -Type Count: 1,000 - === nonnullAssertionPropegatesContextualType.ts === let rect2: SVGRectElement = document.querySelector('.svg-rectangle')!; // Error: Element >rect2 : SVGRectElement diff --git a/tests/baselines/reference/reverseMappedConcretePropertiesInference.symbols b/tests/baselines/reference/reverseMappedConcretePropertiesInference.symbols new file mode 100644 index 0000000000000..6860208f71c05 --- /dev/null +++ b/tests/baselines/reference/reverseMappedConcretePropertiesInference.symbols @@ -0,0 +1,185 @@ +//// [tests/cases/compiler/reverseMappedConcretePropertiesInference.ts] //// + +=== reverseMappedConcretePropertiesInference.ts === +declare function test>(a: { +>test : Symbol(test, Decl(reverseMappedConcretePropertiesInference.ts, 0, 0)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>foo : Symbol(foo, Decl(reverseMappedConcretePropertiesInference.ts, 0, 48)) +>bar : Symbol(bar, Decl(reverseMappedConcretePropertiesInference.ts, 0, 62)) +>a : Symbol(a, Decl(reverseMappedConcretePropertiesInference.ts, 0, 80)) + + [K in keyof T]: { +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 1, 3)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) + + foo: T[K]["foo"]; +>foo : Symbol(foo, Decl(reverseMappedConcretePropertiesInference.ts, 1, 19)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 1, 3)) + + onFoo: (fooArg: T[K]["foo"]) => void; +>onFoo : Symbol(onFoo, Decl(reverseMappedConcretePropertiesInference.ts, 2, 21)) +>fooArg : Symbol(fooArg, Decl(reverseMappedConcretePropertiesInference.ts, 3, 12)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 1, 3)) + + bar: T[K]["bar"]; +>bar : Symbol(bar, Decl(reverseMappedConcretePropertiesInference.ts, 3, 41)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 1, 3)) + + onBar: (barArg: T[K]["bar"]) => void; +>onBar : Symbol(onBar, Decl(reverseMappedConcretePropertiesInference.ts, 4, 21)) +>barArg : Symbol(barArg, Decl(reverseMappedConcretePropertiesInference.ts, 5, 12)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 1, 3)) + + }; +}): T; +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 0, 22)) + +const res = test({ +>res : Symbol(res, Decl(reverseMappedConcretePropertiesInference.ts, 9, 5)) +>test : Symbol(test, Decl(reverseMappedConcretePropertiesInference.ts, 0, 0)) + + a: { +>a : Symbol(a, Decl(reverseMappedConcretePropertiesInference.ts, 9, 18)) + + foo: 'answer', +>foo : Symbol(foo, Decl(reverseMappedConcretePropertiesInference.ts, 10, 8)) + + onFoo: (arg) => arg.length, +>onFoo : Symbol(onFoo, Decl(reverseMappedConcretePropertiesInference.ts, 11, 22)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 12, 16)) +>arg.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 12, 16)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) + + bar: 42, +>bar : Symbol(bar, Decl(reverseMappedConcretePropertiesInference.ts, 12, 35)) + + onBar: (arg) => arg + 10 +>onBar : Symbol(onBar, Decl(reverseMappedConcretePropertiesInference.ts, 13, 16)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 14, 16)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 14, 16)) + + }, + b: { +>b : Symbol(b, Decl(reverseMappedConcretePropertiesInference.ts, 15, 6)) + + foo: true, +>foo : Symbol(foo, Decl(reverseMappedConcretePropertiesInference.ts, 16, 8)) + + onFoo: (arg) => !!arg, +>onFoo : Symbol(onFoo, Decl(reverseMappedConcretePropertiesInference.ts, 17, 18)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 18, 16)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 18, 16)) + + bar: [1, 2, 3], +>bar : Symbol(bar, Decl(reverseMappedConcretePropertiesInference.ts, 18, 30)) + + onBar: (arg) => [arg, arg] +>onBar : Symbol(onBar, Decl(reverseMappedConcretePropertiesInference.ts, 19, 23)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 20, 16)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 20, 16)) +>arg : Symbol(arg, Decl(reverseMappedConcretePropertiesInference.ts, 20, 16)) + + }, +}) + +interface QueryFunctionContext { +>QueryFunctionContext : Symbol(QueryFunctionContext, Decl(reverseMappedConcretePropertiesInference.ts, 22, 2)) +>TQueryKey : Symbol(TQueryKey, Decl(reverseMappedConcretePropertiesInference.ts, 24, 31)) + + queryKey: TQueryKey; +>queryKey : Symbol(QueryFunctionContext.queryKey, Decl(reverseMappedConcretePropertiesInference.ts, 24, 58)) +>TQueryKey : Symbol(TQueryKey, Decl(reverseMappedConcretePropertiesInference.ts, 24, 31)) +} + +type QueryOptions = { +>QueryOptions : Symbol(QueryOptions, Decl(reverseMappedConcretePropertiesInference.ts, 26, 1)) + + key: string; +>key : Symbol(key, Decl(reverseMappedConcretePropertiesInference.ts, 28, 21)) + + fnData?: unknown; +>fnData : Symbol(fnData, Decl(reverseMappedConcretePropertiesInference.ts, 29, 14)) + +}; + +type UseQueriesOptions> = { +>UseQueriesOptions : Symbol(UseQueriesOptions, Decl(reverseMappedConcretePropertiesInference.ts, 31, 2)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --) ... and 3 more) +>QueryOptions : Symbol(QueryOptions, Decl(reverseMappedConcretePropertiesInference.ts, 26, 1)) + + [K in keyof T]: { +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 34, 3)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) + + queryKey: T[K]["key"]; +>queryKey : Symbol(queryKey, Decl(reverseMappedConcretePropertiesInference.ts, 34, 19)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 34, 3)) + + queryFn?: ( +>queryFn : Symbol(queryFn, Decl(reverseMappedConcretePropertiesInference.ts, 35, 26)) + + ctx: QueryFunctionContext +>ctx : Symbol(ctx, Decl(reverseMappedConcretePropertiesInference.ts, 36, 15)) +>QueryFunctionContext : Symbol(QueryFunctionContext, Decl(reverseMappedConcretePropertiesInference.ts, 22, 2)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 34, 3)) + + ) => Promise | T[K]["fnData"]; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 34, 3)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 33, 23)) +>K : Symbol(K, Decl(reverseMappedConcretePropertiesInference.ts, 34, 3)) + + }; +}; + +declare function useQueries>( +>useQueries : Symbol(useQueries, Decl(reverseMappedConcretePropertiesInference.ts, 40, 2)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 42, 28)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --) ... and 3 more) +>QueryOptions : Symbol(QueryOptions, Decl(reverseMappedConcretePropertiesInference.ts, 26, 1)) + + queries: [...UseQueriesOptions] +>queries : Symbol(queries, Decl(reverseMappedConcretePropertiesInference.ts, 42, 67)) +>UseQueriesOptions : Symbol(UseQueriesOptions, Decl(reverseMappedConcretePropertiesInference.ts, 31, 2)) +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 42, 28)) + +): T; +>T : Symbol(T, Decl(reverseMappedConcretePropertiesInference.ts, 42, 28)) + +const resQueries = useQueries([ +>resQueries : Symbol(resQueries, Decl(reverseMappedConcretePropertiesInference.ts, 46, 5)) +>useQueries : Symbol(useQueries, Decl(reverseMappedConcretePropertiesInference.ts, 40, 2)) + { + queryKey: "users", +>queryKey : Symbol(queryKey, Decl(reverseMappedConcretePropertiesInference.ts, 47, 3)) + + queryFn: (key) => [{ name: "Andarist" }], +>queryFn : Symbol(queryFn, Decl(reverseMappedConcretePropertiesInference.ts, 48, 22)) +>key : Symbol(key, Decl(reverseMappedConcretePropertiesInference.ts, 49, 14)) +>name : Symbol(name, Decl(reverseMappedConcretePropertiesInference.ts, 49, 24)) + + }, + { + queryKey: "posts", +>queryKey : Symbol(queryKey, Decl(reverseMappedConcretePropertiesInference.ts, 51, 3)) + + queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), +>queryFn : Symbol(queryFn, Decl(reverseMappedConcretePropertiesInference.ts, 52, 22)) +>key : Symbol(key, Decl(reverseMappedConcretePropertiesInference.ts, 53, 14)) +>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>title : Symbol(title, Decl(reverseMappedConcretePropertiesInference.ts, 53, 40)) + } +]); + diff --git a/tests/baselines/reference/reverseMappedConcretePropertiesInference.types b/tests/baselines/reference/reverseMappedConcretePropertiesInference.types new file mode 100644 index 0000000000000..e1ad9e14f03de --- /dev/null +++ b/tests/baselines/reference/reverseMappedConcretePropertiesInference.types @@ -0,0 +1,272 @@ +//// [tests/cases/compiler/reverseMappedConcretePropertiesInference.ts] //// + +=== reverseMappedConcretePropertiesInference.ts === +declare function test>(a: { +>test : >(a: { [K in keyof T]: { foo: T[K]["foo"]; onFoo: (fooArg: T[K]["foo"]) => void; bar: T[K]["bar"]; onBar: (barArg: T[K]["bar"]) => void; }; }) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>foo : unknown +> : ^^^^^^^ +>bar : unknown +> : ^^^^^^^ +>a : { [K in keyof T]: { foo: T[K]["foo"]; onFoo: (fooArg: T[K]["foo"]) => void; bar: T[K]["bar"]; onBar: (barArg: T[K]["bar"]) => void; }; } +> : ^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^ ^^^^^^^^^ ^^^^^^ + + [K in keyof T]: { + foo: T[K]["foo"]; +>foo : T[K]["foo"] +> : ^^^^^^^^^^^ + + onFoo: (fooArg: T[K]["foo"]) => void; +>onFoo : (fooArg: T[K]["foo"]) => void +> : ^ ^^ ^^^^^ +>fooArg : T[K]["foo"] +> : ^^^^^^^^^^^ + + bar: T[K]["bar"]; +>bar : T[K]["bar"] +> : ^^^^^^^^^^^ + + onBar: (barArg: T[K]["bar"]) => void; +>onBar : (barArg: T[K]["bar"]) => void +> : ^ ^^ ^^^^^ +>barArg : T[K]["bar"] +> : ^^^^^^^^^^^ + + }; +}): T; + +const res = test({ +>res : { a: { foo: string; } & { bar: number; }; b: { foo: boolean; } & { bar: number[]; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>test({ a: { foo: 'answer', onFoo: (arg) => arg.length, bar: 42, onBar: (arg) => arg + 10 }, b: { foo: true, onFoo: (arg) => !!arg, bar: [1, 2, 3], onBar: (arg) => [arg, arg] },}) : { a: { foo: string; } & { bar: number; }; b: { foo: boolean; } & { bar: number[]; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>test : >(a: { [K in keyof T]: { foo: T[K]["foo"]; onFoo: (fooArg: T[K]["foo"]) => void; bar: T[K]["bar"]; onBar: (barArg: T[K]["bar"]) => void; }; }) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>{ a: { foo: 'answer', onFoo: (arg) => arg.length, bar: 42, onBar: (arg) => arg + 10 }, b: { foo: true, onFoo: (arg) => !!arg, bar: [1, 2, 3], onBar: (arg) => [arg, arg] },} : { a: { foo: string; onFoo: (arg: string) => number; bar: number; onBar: (arg: number) => number; }; b: { foo: true; onFoo: (arg: boolean) => boolean; bar: number[]; onBar: (arg: number[]) => number[][]; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + a: { +>a : { foo: string; onFoo: (arg: string) => number; bar: number; onBar: (arg: number) => number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ +>{ foo: 'answer', onFoo: (arg) => arg.length, bar: 42, onBar: (arg) => arg + 10 } : { foo: string; onFoo: (arg: string) => number; bar: number; onBar: (arg: number) => number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ + + foo: 'answer', +>foo : string +> : ^^^^^^ +>'answer' : "answer" +> : ^^^^^^^^ + + onFoo: (arg) => arg.length, +>onFoo : (arg: string) => number +> : ^ ^^^^^^^^^^^^^^^^^^^ +>(arg) => arg.length : (arg: string) => number +> : ^ ^^^^^^^^^^^^^^^^^^^ +>arg : string +> : ^^^^^^ +>arg.length : number +> : ^^^^^^ +>arg : string +> : ^^^^^^ +>length : number +> : ^^^^^^ + + bar: 42, +>bar : number +> : ^^^^^^ +>42 : 42 +> : ^^ + + onBar: (arg) => arg + 10 +>onBar : (arg: number) => number +> : ^ ^^^^^^^^^^^^^^^^^^^ +>(arg) => arg + 10 : (arg: number) => number +> : ^ ^^^^^^^^^^^^^^^^^^^ +>arg : number +> : ^^^^^^ +>arg + 10 : number +> : ^^^^^^ +>arg : number +> : ^^^^^^ +>10 : 10 +> : ^^ + + }, + b: { +>b : { foo: true; onFoo: (arg: boolean) => boolean; bar: number[]; onBar: (arg: number[]) => number[][]; } +> : ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ foo: true, onFoo: (arg) => !!arg, bar: [1, 2, 3], onBar: (arg) => [arg, arg] } : { foo: true; onFoo: (arg: boolean) => boolean; bar: number[]; onBar: (arg: number[]) => number[][]; } +> : ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + foo: true, +>foo : true +> : ^^^^ +>true : true +> : ^^^^ + + onFoo: (arg) => !!arg, +>onFoo : (arg: boolean) => boolean +> : ^ ^^^^^^^^^^^^^^^^^^^^^ +>(arg) => !!arg : (arg: boolean) => boolean +> : ^ ^^^^^^^^^^^^^^^^^^^^^ +>arg : boolean +> : ^^^^^^^ +>!!arg : boolean +> : ^^^^^^^ +>!arg : boolean +> : ^^^^^^^ +>arg : boolean +> : ^^^^^^^ + + bar: [1, 2, 3], +>bar : number[] +> : ^^^^^^^^ +>[1, 2, 3] : number[] +> : ^^^^^^^^ +>1 : 1 +> : ^ +>2 : 2 +> : ^ +>3 : 3 +> : ^ + + onBar: (arg) => [arg, arg] +>onBar : (arg: number[]) => number[][] +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^ +>(arg) => [arg, arg] : (arg: number[]) => number[][] +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^ +>arg : number[] +> : ^^^^^^^^ +>[arg, arg] : number[][] +> : ^^^^^^^^^^ +>arg : number[] +> : ^^^^^^^^ +>arg : number[] +> : ^^^^^^^^ + + }, +}) + +interface QueryFunctionContext { + queryKey: TQueryKey; +>queryKey : TQueryKey +> : ^^^^^^^^^ +} + +type QueryOptions = { +>QueryOptions : QueryOptions +> : ^^^^^^^^^^^^ + + key: string; +>key : string +> : ^^^^^^ + + fnData?: unknown; +>fnData : unknown +> : ^^^^^^^ + +}; + +type UseQueriesOptions> = { +>UseQueriesOptions : UseQueriesOptions +> : ^^^^^^^^^^^^^^^^^^^^ + + [K in keyof T]: { + queryKey: T[K]["key"]; +>queryKey : T[K]["key"] +> : ^^^^^^^^^^^ + + queryFn?: ( +>queryFn : ((ctx: QueryFunctionContext) => Promise | T[K]["fnData"]) | undefined +> : ^^ ^^ ^^^^^ ^^^^^^^^^^^^^ + + ctx: QueryFunctionContext +>ctx : QueryFunctionContext +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ) => Promise | T[K]["fnData"]; + }; +}; + +declare function useQueries>( +>useQueries : >(queries: [...UseQueriesOptions]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + + queries: [...UseQueriesOptions] +>queries : [...UseQueriesOptions] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + +): T; + +const resQueries = useQueries([ +>resQueries : [{ key: "users"; } & { fnData: { name: string; }[]; }, { key: "posts"; } & { fnData: { title: string; }[]; }] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>useQueries([ { queryKey: "users", queryFn: (key) => [{ name: "Andarist" }], }, { queryKey: "posts", queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), }]) : [{ key: "users"; } & { fnData: { name: string; }[]; }, { key: "posts"; } & { fnData: { title: string; }[]; }] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>useQueries : >(queries: [...UseQueriesOptions]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>[ { queryKey: "users", queryFn: (key) => [{ name: "Andarist" }], }, { queryKey: "posts", queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), }] : [{ queryKey: "users"; queryFn: (key: QueryFunctionContext<"users">) => { name: string; }[]; }, { queryKey: "posts"; queryFn: (key: QueryFunctionContext<"posts">) => Promise<{ title: string; }[]>; }] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + { +>{ queryKey: "users", queryFn: (key) => [{ name: "Andarist" }], } : { queryKey: "users"; queryFn: (key: QueryFunctionContext<"users">) => { name: string; }[]; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + queryKey: "users", +>queryKey : "users" +> : ^^^^^^^ +>"users" : "users" +> : ^^^^^^^ + + queryFn: (key) => [{ name: "Andarist" }], +>queryFn : (key: QueryFunctionContext<"users">) => { name: string; }[] +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(key) => [{ name: "Andarist" }] : (key: QueryFunctionContext<"users">) => { name: string; }[] +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>key : QueryFunctionContext<"users"> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[{ name: "Andarist" }] : { name: string; }[] +> : ^^^^^^^^^^^^^^^^^^^ +>{ name: "Andarist" } : { name: string; } +> : ^^^^^^^^^^^^^^^^^ +>name : string +> : ^^^^^^ +>"Andarist" : "Andarist" +> : ^^^^^^^^^^ + + }, + { +>{ queryKey: "posts", queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), } : { queryKey: "posts"; queryFn: (key: QueryFunctionContext<"posts">) => Promise<{ title: string; }[]>; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + queryKey: "posts", +>queryKey : "posts" +> : ^^^^^^^ +>"posts" : "posts" +> : ^^^^^^^ + + queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), +>queryFn : (key: QueryFunctionContext<"posts">) => Promise<{ title: string; }[]> +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(key) => Promise.resolve([{ title: 'TS 5.1' }]) : (key: QueryFunctionContext<"posts">) => Promise<{ title: string; }[]> +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>key : QueryFunctionContext<"posts"> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Promise.resolve([{ title: 'TS 5.1' }]) : Promise<{ title: string; }[]> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Promise.resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>Promise : PromiseConstructor +> : ^^^^^^^^^^^^^^^^^^ +>resolve : { (): Promise; (value: T): Promise>; (value: T | PromiseLike): Promise>; } +> : ^^^^^^ ^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^^ ^^^ +>[{ title: 'TS 5.1' }] : { title: string; }[] +> : ^^^^^^^^^^^^^^^^^^^^ +>{ title: 'TS 5.1' } : { title: string; } +> : ^^^^^^^^^^^^^^^^^^ +>title : string +> : ^^^^^^ +>'TS 5.1' : "TS 5.1" +> : ^^^^^^^^ + } +]); + diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.js b/tests/baselines/reference/thisTypeInObjectLiterals2.js index 2464433ad982f..476590a95247e 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.js +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.js @@ -201,8 +201,6 @@ p12.bar = p12.bar + 1; type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; -type Dictionary = { [x: string]: T } - type Computed = { get?(): T; set?(value: T): void; @@ -470,9 +468,6 @@ declare let p12: Point & { type Accessors = { [K in keyof T]: (() => T[K]) | Computed; }; -type Dictionary = { - [x: string]: T; -}; type Computed = { get?(): T; set?(value: T): void; diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.symbols b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols index b373f4fa07bad..c6714fc806724 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.symbols +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.symbols @@ -647,137 +647,131 @@ type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; >T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 198, 15)) >T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 198, 15)) >K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 198, 23)) ->Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 200, 39)) +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 198, 70)) >T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 198, 15)) >K : Symbol(K, Decl(thisTypeInObjectLiterals2.ts, 198, 23)) -type Dictionary = { [x: string]: T } ->Dictionary : Symbol(Dictionary, Decl(thisTypeInObjectLiterals2.ts, 198, 70)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 200, 16)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 200, 24)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 200, 16)) - type Computed = { ->Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 200, 39)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 202, 14)) +>Computed : Symbol(Computed, Decl(thisTypeInObjectLiterals2.ts, 198, 70)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 200, 14)) get?(): T; ->get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 202, 20)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 202, 14)) +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 200, 20)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 200, 14)) set?(value: T): void; ->set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 203, 14)) ->value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 204, 9)) ->T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 202, 14)) +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 201, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 202, 9)) +>T : Symbol(T, Decl(thisTypeInObjectLiterals2.ts, 200, 14)) } type VueOptions = ThisType & { ->VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 205, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 207, 16)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 207, 18)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 207, 21)) +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 203, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 205, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 205, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 205, 21)) >ThisType : Symbol(ThisType, Decl(lib.es5.d.ts, --, --)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 207, 16)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 207, 18)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 207, 21)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 205, 16)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 205, 18)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 205, 21)) data?: D | (() => D); ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 207, 50)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 207, 16)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 207, 16)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 205, 50)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 205, 16)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 205, 16)) methods?: M; ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 208, 25)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 207, 18)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 206, 25)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 205, 18)) computed?: Accessors

; ->computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 209, 16)) +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 207, 16)) >Accessors : Symbol(Accessors, Decl(thisTypeInObjectLiterals2.ts, 194, 22)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 207, 21)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 205, 21)) } declare const Vue: new (options: VueOptions) => D & M & P; ->Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 213, 13)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 213, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 213, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 213, 29)) ->options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 213, 33)) ->VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 205, 1)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 213, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 213, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 213, 29)) ->D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 213, 24)) ->M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 213, 26)) ->P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 213, 29)) +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 211, 13)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 211, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 211, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 211, 29)) +>options : Symbol(options, Decl(thisTypeInObjectLiterals2.ts, 211, 33)) +>VueOptions : Symbol(VueOptions, Decl(thisTypeInObjectLiterals2.ts, 203, 1)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 211, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 211, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 211, 29)) +>D : Symbol(D, Decl(thisTypeInObjectLiterals2.ts, 211, 24)) +>M : Symbol(M, Decl(thisTypeInObjectLiterals2.ts, 211, 26)) +>P : Symbol(P, Decl(thisTypeInObjectLiterals2.ts, 211, 29)) let vue = new Vue({ ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) ->Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 213, 13)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) +>Vue : Symbol(Vue, Decl(thisTypeInObjectLiterals2.ts, 211, 13)) data: () => ({ x: 1, y: 2 }), ->data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 215, 19)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) ->y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 216, 24)) +>data : Symbol(data, Decl(thisTypeInObjectLiterals2.ts, 213, 19)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) +>y : Symbol(y, Decl(thisTypeInObjectLiterals2.ts, 214, 24)) methods: { ->methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 216, 33)) +>methods : Symbol(methods, Decl(thisTypeInObjectLiterals2.ts, 214, 33)) f(x: string) { ->f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 217, 14)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 218, 10)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 215, 14)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 10)) return this.x; ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) } }, computed: { ->computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 221, 6)) +>computed : Symbol(computed, Decl(thisTypeInObjectLiterals2.ts, 219, 6)) test(): number { ->test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 222, 15)) +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 220, 15)) return this.x; ->this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) +>this.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) }, hello: { ->hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 225, 10)) +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 223, 10)) get() { ->get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 226, 16)) +>get : Symbol(get, Decl(thisTypeInObjectLiterals2.ts, 224, 16)) return "hi"; }, set(value: string) { ->set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 229, 14)) ->value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 230, 16)) +>set : Symbol(set, Decl(thisTypeInObjectLiterals2.ts, 227, 14)) +>value : Symbol(value, Decl(thisTypeInObjectLiterals2.ts, 228, 16)) } } } }); vue; ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) vue.x; ->vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) ->x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 216, 18)) +>vue.x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) +>x : Symbol(x, Decl(thisTypeInObjectLiterals2.ts, 214, 18)) vue.f("abc"); ->vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 217, 14)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) ->f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 217, 14)) +>vue.f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 215, 14)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) +>f : Symbol(f, Decl(thisTypeInObjectLiterals2.ts, 215, 14)) vue.test; ->vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 222, 15)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) ->test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 222, 15)) +>vue.test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 220, 15)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) +>test : Symbol(test, Decl(thisTypeInObjectLiterals2.ts, 220, 15)) vue.hello; ->vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 225, 10)) ->vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 215, 3)) ->hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 225, 10)) +>vue.hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 223, 10)) +>vue : Symbol(vue, Decl(thisTypeInObjectLiterals2.ts, 213, 3)) +>hello : Symbol(hello, Decl(thisTypeInObjectLiterals2.ts, 223, 10)) diff --git a/tests/baselines/reference/thisTypeInObjectLiterals2.types b/tests/baselines/reference/thisTypeInObjectLiterals2.types index 05cb646d4eea8..24b065fb1a91a 100644 --- a/tests/baselines/reference/thisTypeInObjectLiterals2.types +++ b/tests/baselines/reference/thisTypeInObjectLiterals2.types @@ -1056,12 +1056,6 @@ type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; >Accessors : Accessors > : ^^^^^^^^^^^^ -type Dictionary = { [x: string]: T } ->Dictionary : Dictionary -> : ^^^^^^^^^^^^^ ->x : string -> : ^^^^^^ - type Computed = { >Computed : Computed > : ^^^^^^^^^^^ diff --git a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_namespaceSameNameAsIntrinsic.js b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_namespaceSameNameAsIntrinsic.js index 5fa9b66ccb854..eb630a49266cf 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_namespaceSameNameAsIntrinsic.js +++ b/tests/baselines/reference/tsserver/fourslashServer/autoImportProvider_namespaceSameNameAsIntrinsic.js @@ -976,6 +976,12 @@ Info seq [hh:mm:ss:mss] response: "kindModifiers": "declare", "sortText": "15" }, + { + "name": "PartialInference", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, { "name": "Pick", "kind": "type", diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index b48a1f777b87a..395de616d3aba 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -928,6 +928,12 @@ Info seq [hh:mm:ss:mss] response: "kindModifiers": "declare", "sortText": "15" }, + { + "name": "PartialInference", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, { "name": "Pick", "kind": "type", diff --git a/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.symbols b/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.symbols new file mode 100644 index 0000000000000..09fb247613df6 --- /dev/null +++ b/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts] //// + +=== typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts === +interface Expression extends Node { +>Expression : Symbol(Expression, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 0, 0)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 89)) + + _expressionBrand: any; +>_expressionBrand : Symbol(Expression._expressionBrand, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 0, 35)) +} + +declare function setParent(child: T, parent: T["parent"] | undefined): T; +>setParent : Symbol(setParent, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 2, 1)) +>T : Symbol(T, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 27)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 89)) +>child : Symbol(child, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 43)) +>T : Symbol(T, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 27)) +>parent : Symbol(parent, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 52)) +>T : Symbol(T, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 27)) +>T : Symbol(T, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 27)) + +interface Node { +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 89)) + + readonly kind: number; +>kind : Symbol(Node.kind, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 6, 16)) + + readonly parent: Node; +>parent : Symbol(Node.parent, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 7, 26)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 89)) +} + +declare const expr: Expression +>expr : Symbol(expr, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 11, 13)) +>Expression : Symbol(Expression, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 0, 0)) + +declare const node: Node +>node : Symbol(node, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 12, 13)) +>Node : Symbol(Node, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 4, 89)) + +const res = setParent(expr, node) // Expression +>res : Symbol(res, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 14, 5)) +>setParent : Symbol(setParent, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 2, 1)) +>expr : Symbol(expr, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 11, 13)) +>node : Symbol(node, Decl(typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts, 12, 13)) + diff --git a/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.types b/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.types new file mode 100644 index 0000000000000..d8b6553519b12 --- /dev/null +++ b/tests/baselines/reference/typeInferenceAggregateFromIndicesNotAssignableToConstraint.types @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts] //// + +=== typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts === +interface Expression extends Node { + _expressionBrand: any; +>_expressionBrand : any +} + +declare function setParent(child: T, parent: T["parent"] | undefined): T; +>setParent : (child: T, parent: T["parent"] | undefined) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>child : T +> : ^ +>parent : T["parent"] | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^ + +interface Node { + readonly kind: number; +>kind : number +> : ^^^^^^ + + readonly parent: Node; +>parent : Node +> : ^^^^ +} + +declare const expr: Expression +>expr : Expression +> : ^^^^^^^^^^ + +declare const node: Node +>node : Node +> : ^^^^ + +const res = setParent(expr, node) // Expression +>res : Expression +> : ^^^^^^^^^^ +>setParent(expr, node) : Expression +> : ^^^^^^^^^^ +>setParent : (child: T, parent: T["parent"] | undefined) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>expr : Expression +> : ^^^^^^^^^^ +>node : Node +> : ^^^^ + diff --git a/tests/baselines/reference/typeInferenceOnIndexUnion.js b/tests/baselines/reference/typeInferenceOnIndexUnion.js new file mode 100644 index 0000000000000..55543458c73bc --- /dev/null +++ b/tests/baselines/reference/typeInferenceOnIndexUnion.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/typeInferenceOnIndexUnion.ts] //// + +//// [typeInferenceOnIndexUnion.ts] +type Options = { k: "a", a: number } | { k: "b", b: string }; +declare function f(p: T["k"]): T; +const x = f("a"); // expect it to be `{ k: "a", a: number }` + +type Options2 = { k: "a", a: number, c: {} } | { k: "b", b: string, c: {} }; +declare function f2(p: T["k"], c: T["c"]): T; +const x2 = f2("a", { x: 1, y: 2 }); // expect it to be `{ k: "a", a: number, c: {x: number, y: number} }` + + +//// [typeInferenceOnIndexUnion.js] +var x = f("a"); // expect it to be `{ k: "a", a: number }` +var x2 = f2("a", { x: 1, y: 2 }); // expect it to be `{ k: "a", a: number, c: {x: number, y: number} }` diff --git a/tests/baselines/reference/typeInferenceOnIndexUnion.symbols b/tests/baselines/reference/typeInferenceOnIndexUnion.symbols new file mode 100644 index 0000000000000..5c9f90878eb79 --- /dev/null +++ b/tests/baselines/reference/typeInferenceOnIndexUnion.symbols @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/typeInferenceOnIndexUnion.ts] //// + +=== typeInferenceOnIndexUnion.ts === +type Options = { k: "a", a: number } | { k: "b", b: string }; +>Options : Symbol(Options, Decl(typeInferenceOnIndexUnion.ts, 0, 0)) +>k : Symbol(k, Decl(typeInferenceOnIndexUnion.ts, 0, 16)) +>a : Symbol(a, Decl(typeInferenceOnIndexUnion.ts, 0, 24)) +>k : Symbol(k, Decl(typeInferenceOnIndexUnion.ts, 0, 40)) +>b : Symbol(b, Decl(typeInferenceOnIndexUnion.ts, 0, 48)) + +declare function f(p: T["k"]): T; +>f : Symbol(f, Decl(typeInferenceOnIndexUnion.ts, 0, 61)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 1, 19)) +>Options : Symbol(Options, Decl(typeInferenceOnIndexUnion.ts, 0, 0)) +>p : Symbol(p, Decl(typeInferenceOnIndexUnion.ts, 1, 38)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 1, 19)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 1, 19)) + +const x = f("a"); // expect it to be `{ k: "a", a: number }` +>x : Symbol(x, Decl(typeInferenceOnIndexUnion.ts, 2, 5)) +>f : Symbol(f, Decl(typeInferenceOnIndexUnion.ts, 0, 61)) + +type Options2 = { k: "a", a: number, c: {} } | { k: "b", b: string, c: {} }; +>Options2 : Symbol(Options2, Decl(typeInferenceOnIndexUnion.ts, 2, 17)) +>k : Symbol(k, Decl(typeInferenceOnIndexUnion.ts, 4, 17)) +>a : Symbol(a, Decl(typeInferenceOnIndexUnion.ts, 4, 25)) +>c : Symbol(c, Decl(typeInferenceOnIndexUnion.ts, 4, 36)) +>k : Symbol(k, Decl(typeInferenceOnIndexUnion.ts, 4, 48)) +>b : Symbol(b, Decl(typeInferenceOnIndexUnion.ts, 4, 56)) +>c : Symbol(c, Decl(typeInferenceOnIndexUnion.ts, 4, 67)) + +declare function f2(p: T["k"], c: T["c"]): T; +>f2 : Symbol(f2, Decl(typeInferenceOnIndexUnion.ts, 4, 76)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 5, 20)) +>Options2 : Symbol(Options2, Decl(typeInferenceOnIndexUnion.ts, 2, 17)) +>p : Symbol(p, Decl(typeInferenceOnIndexUnion.ts, 5, 40)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 5, 20)) +>c : Symbol(c, Decl(typeInferenceOnIndexUnion.ts, 5, 50)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 5, 20)) +>T : Symbol(T, Decl(typeInferenceOnIndexUnion.ts, 5, 20)) + +const x2 = f2("a", { x: 1, y: 2 }); // expect it to be `{ k: "a", a: number, c: {x: number, y: number} }` +>x2 : Symbol(x2, Decl(typeInferenceOnIndexUnion.ts, 6, 5)) +>f2 : Symbol(f2, Decl(typeInferenceOnIndexUnion.ts, 4, 76)) +>x : Symbol(x, Decl(typeInferenceOnIndexUnion.ts, 6, 20)) +>y : Symbol(y, Decl(typeInferenceOnIndexUnion.ts, 6, 26)) + diff --git a/tests/baselines/reference/typeInferenceOnIndexUnion.types b/tests/baselines/reference/typeInferenceOnIndexUnion.types new file mode 100644 index 0000000000000..028a5b9d51a75 --- /dev/null +++ b/tests/baselines/reference/typeInferenceOnIndexUnion.types @@ -0,0 +1,75 @@ +//// [tests/cases/compiler/typeInferenceOnIndexUnion.ts] //// + +=== typeInferenceOnIndexUnion.ts === +type Options = { k: "a", a: number } | { k: "b", b: string }; +>Options : Options +> : ^^^^^^^ +>k : "a" +> : ^^^ +>a : number +> : ^^^^^^ +>k : "b" +> : ^^^ +>b : string +> : ^^^^^^ + +declare function f(p: T["k"]): T; +>f : (p: T["k"]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>p : T["k"] +> : ^^^^^^ + +const x = f("a"); // expect it to be `{ k: "a", a: number }` +>x : { k: "a"; a: number; } +> : ^^^^^^^^^^^^^ ^^^ +>f("a") : { k: "a"; a: number; } +> : ^^^^^^^^^^^^^ ^^^ +>f : (p: T["k"]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>"a" : "a" +> : ^^^ + +type Options2 = { k: "a", a: number, c: {} } | { k: "b", b: string, c: {} }; +>Options2 : Options2 +> : ^^^^^^^^ +>k : "a" +> : ^^^ +>a : number +> : ^^^^^^ +>c : {} +> : ^^ +>k : "b" +> : ^^^ +>b : string +> : ^^^^^^ +>c : {} +> : ^^ + +declare function f2(p: T["k"], c: T["c"]): T; +>f2 : (p: T["k"], c: T["c"]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>p : T["k"] +> : ^^^^^^ +>c : T["c"] +> : ^^^^^^ + +const x2 = f2("a", { x: 1, y: 2 }); // expect it to be `{ k: "a", a: number, c: {x: number, y: number} }` +>x2 : { k: "a"; c: { x: number; y: number; }; a: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>f2("a", { x: 1, y: 2 }) : { k: "a"; c: { x: number; y: number; }; a: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ +>f2 : (p: T["k"], c: T["c"]) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>"a" : "a" +> : ^^^ +>{ x: 1, y: 2 } : { x: number; y: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>1 : 1 +> : ^ +>y : number +> : ^^^^^^ +>2 : 2 +> : ^ + diff --git a/tests/cases/compiler/indexAccessCombinedInference.ts b/tests/cases/compiler/indexAccessCombinedInference.ts new file mode 100644 index 0000000000000..e72131d320f04 --- /dev/null +++ b/tests/cases/compiler/indexAccessCombinedInference.ts @@ -0,0 +1,108 @@ +// Simple case +interface Args { + TA: object, + TY: object +} + +declare function foo( + a: T["TA"], + b: T["TY"]): T["TA"] & T["TY"]; + +const x = foo({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); + +// Union result type +interface A { + foo: number; +} +interface B { + bar: string; +} +declare const something: A | B; + +const y = foo(something, { bat: 42 }); + +// Union key type +interface Args2 { + TA?: object, // Optional since only one of TA or TB needs to be infered in the below argument list + TB?: object, + TY: object +} +declare function foo2( + a: T["TA"] | T["TB"], + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +declare function foo3( // Morally equivalent to foo2 + a: T["TA" | "TB"], + b: T["TY"]): {a: T["TA"], b: T["TB"]} & T["TY"]; +let z = foo2({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +let zz = foo3({ + x: { + j: 12, + i: 11 + } +}, { y: 42 }); +z = zz; +zz = z; + +// Higher-order +interface Args3 { + Key: "A" | "B", + A: object, + B: object, + Merge: object, +} +declare const either: "A" | "B"; +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"]): T[T["Key"]] & T["Merge"]; + +const opt1 = pickOne("A", {x: 12}, {y: ""}, {z: /./}); +const opt2 = pickOne("B", {x: 12}, {y: ""}, {z: /./}); +const opt3 = pickOne(either, {x: 12}, {y: ""}, {z: /./}); + +const pickDelayed = (x: TKey) => pickOne(x, {j: x}, {i: x}, {chosen: x}); +const opt4 = pickDelayed("A"); +const opt5 = pickDelayed("B"); +const opt6 = pickDelayed(either); + +// Reopenable +interface Args3 { + /** + * One must make patched parameters optional, otherwise signatures expecting the unpatched + * interface (ie, pickOne above) will not be able to produce a type satisfying the interface + * (as there are no inference sites for the new members) and will fall back to the constraints on each member + */ + Extra?: object, +} +declare function pickOne(key: T["Key"], left: T["A"], right: T["B"], into: T["Merge"], extra: T["Extra"]): T[T["Key"]] & {into: T["Merge"], extra: T["Extra"]}; +const opt7 = pickOne("A", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +const opt8 = pickOne("B", {x: 12}, {y: ""}, {z: /./}, {z: /./}); +const opt9 = pickOne(either, {x: 12}, {y: ""}, {z: /./}, {z: /./}); + +// Interactions with `this` types +interface TPicker { + Key: keyof this, + X: number, + Y: string +} +declare function chooseLiteral(choice: T["Key"], x: T["X"], y:T["Y"]): T[T["Key"]]; +const cx = chooseLiteral("X", 1, "no"); +const cy = chooseLiteral("Y", 0, "yes"); +const ceither = chooseLiteral("X" as "X" | "Y", 1, "yes"); +const cneither = chooseLiteral("Key", 0, "no"); + +// Multiple inference sites +interface Args4 { + 0: object, + 1: Record, +} +declare function dualInputs(x: T[0], y: T[0], toDelay: T[1]): T[0] & {transformers: T[1]}; + +const result = dualInputs({x: 0}, {x: 1}, {x: () => ""}); diff --git a/tests/cases/compiler/reverseMappedConcretePropertiesInference.ts b/tests/cases/compiler/reverseMappedConcretePropertiesInference.ts new file mode 100644 index 0000000000000..d5a13fe36d5b9 --- /dev/null +++ b/tests/cases/compiler/reverseMappedConcretePropertiesInference.ts @@ -0,0 +1,60 @@ +// @strict: true +// @lib: esnext +// @noEmit: true + +declare function test>(a: { + [K in keyof T]: { + foo: T[K]["foo"]; + onFoo: (fooArg: T[K]["foo"]) => void; + bar: T[K]["bar"]; + onBar: (barArg: T[K]["bar"]) => void; + }; +}): T; + +const res = test({ + a: { + foo: 'answer', + onFoo: (arg) => arg.length, + bar: 42, + onBar: (arg) => arg + 10 + }, + b: { + foo: true, + onFoo: (arg) => !!arg, + bar: [1, 2, 3], + onBar: (arg) => [arg, arg] + }, +}) + +interface QueryFunctionContext { + queryKey: TQueryKey; +} + +type QueryOptions = { + key: string; + fnData?: unknown; +}; + +type UseQueriesOptions> = { + [K in keyof T]: { + queryKey: T[K]["key"]; + queryFn?: ( + ctx: QueryFunctionContext + ) => Promise | T[K]["fnData"]; + }; +}; + +declare function useQueries>( + queries: [...UseQueriesOptions] +): T; + +const resQueries = useQueries([ + { + queryKey: "users", + queryFn: (key) => [{ name: "Andarist" }], + }, + { + queryKey: "posts", + queryFn: (key) => Promise.resolve([{ title: 'TS 5.1' }]), + } +]); diff --git a/tests/cases/compiler/typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts b/tests/cases/compiler/typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts new file mode 100644 index 0000000000000..0b3a82685c793 --- /dev/null +++ b/tests/cases/compiler/typeInferenceAggregateFromIndicesNotAssignableToConstraint.ts @@ -0,0 +1,18 @@ +// @strict: true +// @noEmit: true + +interface Expression extends Node { + _expressionBrand: any; +} + +declare function setParent(child: T, parent: T["parent"] | undefined): T; + +interface Node { + readonly kind: number; + readonly parent: Node; +} + +declare const expr: Expression +declare const node: Node + +const res = setParent(expr, node) // Expression \ No newline at end of file diff --git a/tests/cases/compiler/typeInferenceOnIndexUnion.ts b/tests/cases/compiler/typeInferenceOnIndexUnion.ts new file mode 100644 index 0000000000000..35c5fb16a9fa8 --- /dev/null +++ b/tests/cases/compiler/typeInferenceOnIndexUnion.ts @@ -0,0 +1,7 @@ +type Options = { k: "a", a: number } | { k: "b", b: string }; +declare function f(p: T["k"]): T; +const x = f("a"); // expect it to be `{ k: "a", a: number }` + +type Options2 = { k: "a", a: number, c: {} } | { k: "b", b: string, c: {} }; +declare function f2(p: T["k"], c: T["c"]): T; +const x2 = f2("a", { x: 1, y: 2 }); // expect it to be `{ k: "a", a: number, c: {x: number, y: number} }` diff --git a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts index 27861f81da6a6..3a47f85fe4cca 100644 --- a/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts +++ b/tests/cases/conformance/types/thisType/thisTypeInObjectLiterals2.ts @@ -202,8 +202,6 @@ p12.bar = p12.bar + 1; type Accessors = { [K in keyof T]: (() => T[K]) | Computed }; -type Dictionary = { [x: string]: T } - type Computed = { get?(): T; set?(value: T): void;