From 1cdbfeec4cbe927bb68c12c22503aece6a48cb1c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 21 Jan 2021 15:33:25 -0800 Subject: [PATCH 1/2] Add instantiation rules for reverse mapped types --- src/compiler/checker.ts | 25 ++- ...genericFunctionsAndConditionalInference.js | 38 +++++ ...icFunctionsAndConditionalInference.symbols | 147 ++++++++++++++++++ ...ericFunctionsAndConditionalInference.types | 100 ++++++++++++ ...genericFunctionsAndConditionalInference.ts | 27 ++++ 5 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/genericFunctionsAndConditionalInference.js create mode 100644 tests/baselines/reference/genericFunctionsAndConditionalInference.symbols create mode 100644 tests/baselines/reference/genericFunctionsAndConditionalInference.types create mode 100644 tests/cases/compiler/genericFunctionsAndConditionalInference.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index efb46b2efbdfc..111bf76265e93 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15740,6 +15740,9 @@ namespace ts { const newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper); return newTypeArguments !== resolvedTypeArguments ? createNormalizedTypeReference((type).target, newTypeArguments) : type; } + if (objectFlags & ObjectFlags.ReverseMapped) { + return instantiateReverseMappedType(type as ReverseMappedType, mapper); + } return getObjectTypeInstantiation(type, mapper, aliasSymbol, aliasTypeArguments); } return type; @@ -15790,6 +15793,26 @@ namespace ts { return type; } + function instantiateReverseMappedType(type: ReverseMappedType, mapper: TypeMapper) { + const innerMappedType = instantiateType(type.mappedType, mapper); + if (!(getObjectFlags(innerMappedType) & ObjectFlags.Mapped)) { + return type; + } + const innerIndexType = instantiateType(type.constraintType, mapper); + if (!(innerIndexType.flags & TypeFlags.Index)) { + return type; + } + const instantiated = inferTypeForHomomorphicMappedType( + instantiateType(type.source, mapper), + innerMappedType as MappedType, + innerIndexType as IndexType + ); + if (instantiated) { + return instantiated; + } + return type; // Nested invocation of `inferTypeForHomomorphicMappedType` or the `source` instantiated into something unmappable + } + function getPermissiveInstantiation(type: Type) { return type.flags & (TypeFlags.Primitive | TypeFlags.AnyOrUnknown | TypeFlags.Never) ? type : type.permissiveInstantiation || (type.permissiveInstantiation = instantiateType(type, permissiveMapper)); @@ -20147,7 +20170,7 @@ namespace ts { type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && ( objectFlags & ObjectFlags.Reference && ((type).node || forEach(getTypeArguments(type), couldContainTypeVariables)) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || - objectFlags & (ObjectFlags.Mapped | ObjectFlags.ObjectRestType)) || + objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType)) || type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type).types, couldContainTypeVariables)); if (type.flags & TypeFlags.ObjectFlagsType) { (type).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.js b/tests/baselines/reference/genericFunctionsAndConditionalInference.js new file mode 100644 index 0000000000000..a42021275decb --- /dev/null +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.js @@ -0,0 +1,38 @@ +//// [genericFunctionsAndConditionalInference.ts] +interface Targets { + left: A + right: A +} +type Target = keyof Targets +type Result = Targets[F] + +type LR = [F] extends ["left"] ? L : R + +interface Ops { + _f: F + str: Result + num: Result + lr(a: Result, o: Result): Result> + dict:

(p: {[k in keyof P]: Result}) => Result +} +const left: Ops<"left"> = {} as any +const right: Ops<"right"> = {} as any + +const ok = (at: Ops) => ({lr: at.lr(at.str, at.num)}) +const orphaned = (at: Ops) => at.dict(ok(at)) + +const leftOk = ok(left) +const leftOrphaned = orphaned(left) + +const rightOk = ok(right) +const rightOrphaned = orphaned(right) + +//// [genericFunctionsAndConditionalInference.js] +var left = {}; +var right = {}; +var ok = function (at) { return ({ lr: at.lr(at.str, at.num) }); }; +var orphaned = function (at) { return at.dict(ok(at)); }; +var leftOk = ok(left); +var leftOrphaned = orphaned(left); +var rightOk = ok(right); +var rightOrphaned = orphaned(right); diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols b/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols new file mode 100644 index 0000000000000..26b6da0a7c5fb --- /dev/null +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols @@ -0,0 +1,147 @@ +=== tests/cases/compiler/genericFunctionsAndConditionalInference.ts === +interface Targets { +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) + + left: A +>left : Symbol(Targets.left, Decl(genericFunctionsAndConditionalInference.ts, 0, 22)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) + + right: A +>right : Symbol(Targets.right, Decl(genericFunctionsAndConditionalInference.ts, 1, 11)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) +} +type Target = keyof Targets +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) + +type Result = Targets[F] +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 5, 12)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 5, 29)) +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 5, 29)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 5, 12)) + +type LR = [F] extends ["left"] ? L : R +>LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 5, 48)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 7, 8)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 7, 25)) +>R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 7, 28)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 7, 8)) +>L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 7, 25)) +>R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 7, 28)) + +interface Ops { +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) + + _f: F +>_f : Symbol(Ops._f, Decl(genericFunctionsAndConditionalInference.ts, 9, 33)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) + + str: Result +>str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) + + num: Result +>num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) + + lr(a: Result, o: Result): Result> +>lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) +>a : Symbol(a, Decl(genericFunctionsAndConditionalInference.ts, 13, 13)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) +>o : Symbol(o, Decl(genericFunctionsAndConditionalInference.ts, 13, 29)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 5, 48)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) + + dict:

(p: {[k in keyof P]: Result}) => Result +>dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) +>p : Symbol(p, Decl(genericFunctionsAndConditionalInference.ts, 14, 14)) +>k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 14, 19)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) +>k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 14, 19)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) +} +const left: Ops<"left"> = {} as any +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) + +const right: Ops<"right"> = {} as any +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) + +const ok = (at: Ops) => ({lr: at.lr(at.str, at.num)}) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 19, 12)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 19, 12)) +>lr : Symbol(lr, Decl(genericFunctionsAndConditionalInference.ts, 19, 47)) +>at.lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) +>lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) +>at.str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) +>str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) +>at.num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) +>num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) + +const orphaned = (at: Ops) => at.dict(ok(at)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 18)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 18)) +>at.dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) +>dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) + +const leftOk = ok(left) +>leftOk : Symbol(leftOk, Decl(genericFunctionsAndConditionalInference.ts, 22, 5)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) + +const leftOrphaned = orphaned(left) +>leftOrphaned : Symbol(leftOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 23, 5)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) + +const rightOk = ok(right) +>rightOk : Symbol(rightOk, Decl(genericFunctionsAndConditionalInference.ts, 25, 5)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) + +const rightOrphaned = orphaned(right) +>rightOrphaned : Symbol(rightOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 26, 5)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) + diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.types b/tests/baselines/reference/genericFunctionsAndConditionalInference.types new file mode 100644 index 0000000000000..a17e2e70d0b39 --- /dev/null +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.types @@ -0,0 +1,100 @@ +=== tests/cases/compiler/genericFunctionsAndConditionalInference.ts === +interface Targets { + left: A +>left : A + + right: A +>right : A +} +type Target = keyof Targets +>Target : keyof Targets + +type Result = Targets[F] +>Result : Result + +type LR = [F] extends ["left"] ? L : R +>LR : LR + +interface Ops { + _f: F +>_f : F + + str: Result +>str : Result + + num: Result +>num : Result + + lr(a: Result, o: Result): Result> +>lr : (a: Result, o: Result) => Result> +>a : Result +>o : Result + + dict:

(p: {[k in keyof P]: Result}) => Result +>dict :

(p: { [k in keyof P]: Result; }) => Result +>p : { [k in keyof P]: Result; } +} +const left: Ops<"left"> = {} as any +>left : Ops<"left"> +>{} as any : any +>{} : {} + +const right: Ops<"right"> = {} as any +>right : Ops<"right"> +>{} as any : any +>{} : {} + +const ok = (at: Ops) => ({lr: at.lr(at.str, at.num)}) +>ok : >(at: Ops) => { lr: Result>; } +>(at: Ops) => ({lr: at.lr(at.str, at.num)}) : >(at: Ops) => { lr: Result>; } +>at : Ops +>({lr: at.lr(at.str, at.num)}) : { lr: Result>; } +>{lr: at.lr(at.str, at.num)} : { lr: Result>; } +>lr : Result> +>at.lr(at.str, at.num) : Result> +>at.lr : (a: Result, o: Result) => Result> +>at : Ops +>lr : (a: Result, o: Result) => Result> +>at.str : Result +>at : Ops +>str : Result +>at.num : Result +>at : Ops +>num : Result + +const orphaned = (at: Ops) => at.dict(ok(at)) +>orphaned : >(at: Ops) => Result; }> +>(at: Ops) => at.dict(ok(at)) : >(at: Ops) => Result; }> +>at : Ops +>at.dict(ok(at)) : Result; }> +>at.dict :

(p: { [k in keyof P]: Result; }) => Result +>at : Ops +>dict :

(p: { [k in keyof P]: Result; }) => Result +>ok(at) : { lr: Result>; } +>ok : >(at: Ops) => { lr: Result>; } +>at : Ops + +const leftOk = ok(left) +>leftOk : { lr: string; } +>ok(left) : { lr: string; } +>ok : >(at: Ops) => { lr: Result>; } +>left : Ops<"left"> + +const leftOrphaned = orphaned(left) +>leftOrphaned : { lr: string; } +>orphaned(left) : { lr: string; } +>orphaned : >(at: Ops) => Result; }> +>left : Ops<"left"> + +const rightOk = ok(right) +>rightOk : { lr: number; } +>ok(right) : { lr: number; } +>ok : >(at: Ops) => { lr: Result>; } +>right : Ops<"right"> + +const rightOrphaned = orphaned(right) +>rightOrphaned : { lr: number; } +>orphaned(right) : { lr: number; } +>orphaned : >(at: Ops) => Result; }> +>right : Ops<"right"> + diff --git a/tests/cases/compiler/genericFunctionsAndConditionalInference.ts b/tests/cases/compiler/genericFunctionsAndConditionalInference.ts new file mode 100644 index 0000000000000..2b5a39c397962 --- /dev/null +++ b/tests/cases/compiler/genericFunctionsAndConditionalInference.ts @@ -0,0 +1,27 @@ +interface Targets { + left: A + right: A +} +type Target = keyof Targets +type Result = Targets[F] + +type LR = [F] extends ["left"] ? L : R + +interface Ops { + _f: F + str: Result + num: Result + lr(a: Result, o: Result): Result> + dict:

(p: {[k in keyof P]: Result}) => Result +} +const left: Ops<"left"> = {} as any +const right: Ops<"right"> = {} as any + +const ok = (at: Ops) => ({lr: at.lr(at.str, at.num)}) +const orphaned = (at: Ops) => at.dict(ok(at)) + +const leftOk = ok(left) +const leftOrphaned = orphaned(left) + +const rightOk = ok(right) +const rightOrphaned = orphaned(right) \ No newline at end of file From eec6c4605db7d9812f6cda3bbe78fb206bc1a0c8 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 27 Jan 2021 15:47:15 -0800 Subject: [PATCH 2/2] Add smaller example of same issue --- ...genericFunctionsAndConditionalInference.js | 15 ++ ...icFunctionsAndConditionalInference.symbols | 255 ++++++++++-------- ...ericFunctionsAndConditionalInference.types | 37 +++ ...genericFunctionsAndConditionalInference.ts | 11 + 4 files changed, 212 insertions(+), 106 deletions(-) diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.js b/tests/baselines/reference/genericFunctionsAndConditionalInference.js index a42021275decb..ff2f0dbbb627f 100644 --- a/tests/baselines/reference/genericFunctionsAndConditionalInference.js +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.js @@ -1,4 +1,15 @@ //// [genericFunctionsAndConditionalInference.ts] +type Boxified = { [P in keyof T]: { value: T[P]} }; + +declare function unboxify(obj: Boxified): T; + +function foo(obj: { u: { value: U }, v: { value: V } }) { + return unboxify(obj); +} + +let qq = foo({ u: { value: 10 }, v: { value: 'hello'} }); // { u: U, v: V } but should be { u: number, v: string } + +// From #42385 interface Targets { left: A right: A @@ -28,6 +39,10 @@ const rightOk = ok(right) const rightOrphaned = orphaned(right) //// [genericFunctionsAndConditionalInference.js] +function foo(obj) { + return unboxify(obj); +} +var qq = foo({ u: { value: 10 }, v: { value: 'hello' } }); // { u: U, v: V } but should be { u: number, v: string } var left = {}; var right = {}; var ok = function (at) { return ({ lr: at.lr(at.str, at.num) }); }; diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols b/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols index 26b6da0a7c5fb..0e465ba6f7ca5 100644 --- a/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.symbols @@ -1,147 +1,190 @@ === tests/cases/compiler/genericFunctionsAndConditionalInference.ts === +type Boxified = { [P in keyof T]: { value: T[P]} }; +>Boxified : Symbol(Boxified, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 0, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 0, 22)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 0, 14)) +>value : Symbol(value, Decl(genericFunctionsAndConditionalInference.ts, 0, 38)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 0, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 0, 22)) + +declare function unboxify(obj: Boxified): T; +>unboxify : Symbol(unboxify, Decl(genericFunctionsAndConditionalInference.ts, 0, 54)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 2, 26)) +>obj : Symbol(obj, Decl(genericFunctionsAndConditionalInference.ts, 2, 29)) +>Boxified : Symbol(Boxified, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 2, 26)) +>T : Symbol(T, Decl(genericFunctionsAndConditionalInference.ts, 2, 26)) + +function foo(obj: { u: { value: U }, v: { value: V } }) { +>foo : Symbol(foo, Decl(genericFunctionsAndConditionalInference.ts, 2, 50)) +>U : Symbol(U, Decl(genericFunctionsAndConditionalInference.ts, 4, 13)) +>V : Symbol(V, Decl(genericFunctionsAndConditionalInference.ts, 4, 15)) +>obj : Symbol(obj, Decl(genericFunctionsAndConditionalInference.ts, 4, 19)) +>u : Symbol(u, Decl(genericFunctionsAndConditionalInference.ts, 4, 25)) +>value : Symbol(value, Decl(genericFunctionsAndConditionalInference.ts, 4, 30)) +>U : Symbol(U, Decl(genericFunctionsAndConditionalInference.ts, 4, 13)) +>v : Symbol(v, Decl(genericFunctionsAndConditionalInference.ts, 4, 42)) +>value : Symbol(value, Decl(genericFunctionsAndConditionalInference.ts, 4, 47)) +>V : Symbol(V, Decl(genericFunctionsAndConditionalInference.ts, 4, 15)) + + return unboxify(obj); +>unboxify : Symbol(unboxify, Decl(genericFunctionsAndConditionalInference.ts, 0, 54)) +>obj : Symbol(obj, Decl(genericFunctionsAndConditionalInference.ts, 4, 19)) +} + +let qq = foo({ u: { value: 10 }, v: { value: 'hello'} }); // { u: U, v: V } but should be { u: number, v: string } +>qq : Symbol(qq, Decl(genericFunctionsAndConditionalInference.ts, 8, 3)) +>foo : Symbol(foo, Decl(genericFunctionsAndConditionalInference.ts, 2, 50)) +>u : Symbol(u, Decl(genericFunctionsAndConditionalInference.ts, 8, 14)) +>value : Symbol(value, Decl(genericFunctionsAndConditionalInference.ts, 8, 19)) +>v : Symbol(v, Decl(genericFunctionsAndConditionalInference.ts, 8, 32)) +>value : Symbol(value, Decl(genericFunctionsAndConditionalInference.ts, 8, 37)) + +// From #42385 interface Targets { ->Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) ->A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 8, 57)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 11, 18)) left: A ->left : Symbol(Targets.left, Decl(genericFunctionsAndConditionalInference.ts, 0, 22)) ->A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) +>left : Symbol(Targets.left, Decl(genericFunctionsAndConditionalInference.ts, 11, 22)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 11, 18)) right: A ->right : Symbol(Targets.right, Decl(genericFunctionsAndConditionalInference.ts, 1, 11)) ->A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 0, 18)) +>right : Symbol(Targets.right, Decl(genericFunctionsAndConditionalInference.ts, 12, 11)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 11, 18)) } type Target = keyof Targets ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) ->Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 8, 57)) type Result = Targets[F] ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 5, 12)) ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) ->A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 5, 29)) ->Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 0, 0)) ->A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 5, 29)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 5, 12)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 16, 12)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 16, 29)) +>Targets : Symbol(Targets, Decl(genericFunctionsAndConditionalInference.ts, 8, 57)) +>A : Symbol(A, Decl(genericFunctionsAndConditionalInference.ts, 16, 29)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 16, 12)) type LR = [F] extends ["left"] ? L : R ->LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 5, 48)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 7, 8)) ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) ->L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 7, 25)) ->R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 7, 28)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 7, 8)) ->L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 7, 25)) ->R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 7, 28)) +>LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 16, 48)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 18, 8)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) +>L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 18, 25)) +>R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 18, 28)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 18, 8)) +>L : Symbol(L, Decl(genericFunctionsAndConditionalInference.ts, 18, 25)) +>R : Symbol(R, Decl(genericFunctionsAndConditionalInference.ts, 18, 28)) interface Ops { ->Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 18, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) _f: F ->_f : Symbol(Ops._f, Decl(genericFunctionsAndConditionalInference.ts, 9, 33)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>_f : Symbol(Ops._f, Decl(genericFunctionsAndConditionalInference.ts, 20, 33)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) str: Result ->str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 21, 9)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) num: Result ->num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) +>num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 22, 26)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) lr(a: Result, o: Result): Result> ->lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) ->I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) ->O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) ->a : Symbol(a, Decl(genericFunctionsAndConditionalInference.ts, 13, 13)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) ->o : Symbol(o, Decl(genericFunctionsAndConditionalInference.ts, 13, 29)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 5, 48)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 13, 7)) ->O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 13, 9)) +>lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 23, 26)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 24, 7)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 24, 9)) +>a : Symbol(a, Decl(genericFunctionsAndConditionalInference.ts, 24, 13)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 24, 7)) +>o : Symbol(o, Decl(genericFunctionsAndConditionalInference.ts, 24, 29)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 24, 9)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>LR : Symbol(LR, Decl(genericFunctionsAndConditionalInference.ts, 16, 48)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>I : Symbol(I, Decl(genericFunctionsAndConditionalInference.ts, 24, 7)) +>O : Symbol(O, Decl(genericFunctionsAndConditionalInference.ts, 24, 9)) dict:

(p: {[k in keyof P]: Result}) => Result ->dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) ->P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) ->p : Symbol(p, Decl(genericFunctionsAndConditionalInference.ts, 14, 14)) ->k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 14, 19)) ->P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) ->k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 14, 19)) ->Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 4, 32)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 9, 14)) ->P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 14, 11)) +>dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 24, 70)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 25, 11)) +>p : Symbol(p, Decl(genericFunctionsAndConditionalInference.ts, 25, 14)) +>k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 25, 19)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 25, 11)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 25, 11)) +>k : Symbol(k, Decl(genericFunctionsAndConditionalInference.ts, 25, 19)) +>Result : Symbol(Result, Decl(genericFunctionsAndConditionalInference.ts, 15, 32)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 14)) +>P : Symbol(P, Decl(genericFunctionsAndConditionalInference.ts, 25, 11)) } const left: Ops<"left"> = {} as any ->left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) ->Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 27, 5)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 18, 62)) const right: Ops<"right"> = {} as any ->right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) ->Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 28, 5)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 18, 62)) const ok = (at: Ops) => ({lr: at.lr(at.str, at.num)}) ->ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 19, 12)) ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) ->Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 19, 12)) ->lr : Symbol(lr, Decl(genericFunctionsAndConditionalInference.ts, 19, 47)) ->at.lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) ->lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 12, 26)) ->at.str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) ->str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 10, 9)) ->at.num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 19, 30)) ->num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 11, 26)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 30, 5)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 30, 12)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 30, 30)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 18, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 30, 12)) +>lr : Symbol(lr, Decl(genericFunctionsAndConditionalInference.ts, 30, 47)) +>at.lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 23, 26)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 30, 30)) +>lr : Symbol(Ops.lr, Decl(genericFunctionsAndConditionalInference.ts, 23, 26)) +>at.str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 21, 9)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 30, 30)) +>str : Symbol(Ops.str, Decl(genericFunctionsAndConditionalInference.ts, 21, 9)) +>at.num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 22, 26)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 30, 30)) +>num : Symbol(Ops.num, Decl(genericFunctionsAndConditionalInference.ts, 22, 26)) const orphaned = (at: Ops) => at.dict(ok(at)) ->orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 18)) ->Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 3, 1)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) ->Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 7, 62)) ->F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 20, 18)) ->at.dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) ->dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 13, 70)) ->ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) ->at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 20, 36)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 31, 5)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 31, 18)) +>Target : Symbol(Target, Decl(genericFunctionsAndConditionalInference.ts, 14, 1)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 31, 36)) +>Ops : Symbol(Ops, Decl(genericFunctionsAndConditionalInference.ts, 18, 62)) +>F : Symbol(F, Decl(genericFunctionsAndConditionalInference.ts, 31, 18)) +>at.dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 24, 70)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 31, 36)) +>dict : Symbol(Ops.dict, Decl(genericFunctionsAndConditionalInference.ts, 24, 70)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 30, 5)) +>at : Symbol(at, Decl(genericFunctionsAndConditionalInference.ts, 31, 36)) const leftOk = ok(left) ->leftOk : Symbol(leftOk, Decl(genericFunctionsAndConditionalInference.ts, 22, 5)) ->ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) ->left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) +>leftOk : Symbol(leftOk, Decl(genericFunctionsAndConditionalInference.ts, 33, 5)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 30, 5)) +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 27, 5)) const leftOrphaned = orphaned(left) ->leftOrphaned : Symbol(leftOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 23, 5)) ->orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) ->left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 16, 5)) +>leftOrphaned : Symbol(leftOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 34, 5)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 31, 5)) +>left : Symbol(left, Decl(genericFunctionsAndConditionalInference.ts, 27, 5)) const rightOk = ok(right) ->rightOk : Symbol(rightOk, Decl(genericFunctionsAndConditionalInference.ts, 25, 5)) ->ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 19, 5)) ->right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) +>rightOk : Symbol(rightOk, Decl(genericFunctionsAndConditionalInference.ts, 36, 5)) +>ok : Symbol(ok, Decl(genericFunctionsAndConditionalInference.ts, 30, 5)) +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 28, 5)) const rightOrphaned = orphaned(right) ->rightOrphaned : Symbol(rightOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 26, 5)) ->orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 20, 5)) ->right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 17, 5)) +>rightOrphaned : Symbol(rightOrphaned, Decl(genericFunctionsAndConditionalInference.ts, 37, 5)) +>orphaned : Symbol(orphaned, Decl(genericFunctionsAndConditionalInference.ts, 31, 5)) +>right : Symbol(right, Decl(genericFunctionsAndConditionalInference.ts, 28, 5)) diff --git a/tests/baselines/reference/genericFunctionsAndConditionalInference.types b/tests/baselines/reference/genericFunctionsAndConditionalInference.types index a17e2e70d0b39..f545b8ea81246 100644 --- a/tests/baselines/reference/genericFunctionsAndConditionalInference.types +++ b/tests/baselines/reference/genericFunctionsAndConditionalInference.types @@ -1,4 +1,41 @@ === tests/cases/compiler/genericFunctionsAndConditionalInference.ts === +type Boxified = { [P in keyof T]: { value: T[P]} }; +>Boxified : Boxified +>value : T[P] + +declare function unboxify(obj: Boxified): T; +>unboxify : (obj: Boxified) => T +>obj : Boxified + +function foo(obj: { u: { value: U }, v: { value: V } }) { +>foo : (obj: { u: { value: U; }; v: { value: V; };}) => { u: U; v: V; } +>obj : { u: { value: U;}; v: { value: V;}; } +>u : { value: U; } +>value : U +>v : { value: V; } +>value : V + + return unboxify(obj); +>unboxify(obj) : { u: U; v: V; } +>unboxify : (obj: Boxified) => T +>obj : { u: { value: U; }; v: { value: V; }; } +} + +let qq = foo({ u: { value: 10 }, v: { value: 'hello'} }); // { u: U, v: V } but should be { u: number, v: string } +>qq : { u: number; v: string; } +>foo({ u: { value: 10 }, v: { value: 'hello'} }) : { u: number; v: string; } +>foo : (obj: { u: { value: U; }; v: { value: V; }; }) => { u: U; v: V; } +>{ u: { value: 10 }, v: { value: 'hello'} } : { u: { value: number; }; v: { value: string; }; } +>u : { value: number; } +>{ value: 10 } : { value: number; } +>value : number +>10 : 10 +>v : { value: string; } +>{ value: 'hello'} : { value: string; } +>value : string +>'hello' : "hello" + +// From #42385 interface Targets { left: A >left : A diff --git a/tests/cases/compiler/genericFunctionsAndConditionalInference.ts b/tests/cases/compiler/genericFunctionsAndConditionalInference.ts index 2b5a39c397962..de55c5152a5cb 100644 --- a/tests/cases/compiler/genericFunctionsAndConditionalInference.ts +++ b/tests/cases/compiler/genericFunctionsAndConditionalInference.ts @@ -1,3 +1,14 @@ +type Boxified = { [P in keyof T]: { value: T[P]} }; + +declare function unboxify(obj: Boxified): T; + +function foo(obj: { u: { value: U }, v: { value: V } }) { + return unboxify(obj); +} + +let qq = foo({ u: { value: 10 }, v: { value: 'hello'} }); // { u: U, v: V } but should be { u: number, v: string } + +// From #42385 interface Targets { left: A right: A