From 53cb993a282e13b34e4eda2e14a36e4436c2d8ab Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 28 Mar 2018 13:16:11 -0700 Subject: [PATCH 01/18] Erase 'infer T' locations in conditional type constraints --- src/compiler/checker.ts | 14 ++++++++++++-- src/compiler/types.ts | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 479f97a89f12c..4228c6e7c7cd2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6208,7 +6208,7 @@ namespace ts { } function getDefaultConstraintOfConditionalType(type: ConditionalType) { - return getUnionType([getTrueTypeFromConditionalType(type), getFalseTypeFromConditionalType(type)]); + return getUnionType([getInferredTrueTypeFromConditionalType(type), getFalseTypeFromConditionalType(type)]); } function getConstraintOfDistributiveConditionalType(type: ConditionalType): Type { @@ -8338,16 +8338,19 @@ namespace ts { // If this is a distributive conditional type and the check type is generic we need to defer // resolution of the conditional type such that a later instantiation will properly distribute // over union types. - if (!root.isDistributive || !maybeTypeOfKind(checkType, TypeFlags.Instantiable)) { + const isDeferred = root.isDistributive && maybeTypeOfKind(checkType, TypeFlags.Instantiable); let combinedMapper: TypeMapper; if (root.inferTypeParameters) { const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None); + if (!isDeferred) { // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. inferTypes(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + } combinedMapper = combineTypeMappers(mapper, context); } + if (!isDeferred) { // Return union of trueType and falseType for 'any' since it matches anything if (checkType.flags & TypeFlags.Any) { return getUnionType([instantiateType(root.trueType, combinedMapper || mapper), instantiateType(root.falseType, mapper)]); @@ -8376,6 +8379,7 @@ namespace ts { result.checkType = erasedCheckType; result.extendsType = extendsType; result.mapper = mapper; + result.combinedMapper = combinedMapper; result.aliasSymbol = root.aliasSymbol; result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper); return result; @@ -8389,6 +8393,12 @@ namespace ts { return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper)); } + function getInferredTrueTypeFromConditionalType(type: ConditionalType) { + return type.combinedMapper ? + type.resolvedInferredTrueType || (type.resolvedInferredTrueType = instantiateType(type.root.trueType, type.combinedMapper)) : + getTrueTypeFromConditionalType(type); + } + function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] { let result: TypeParameter[]; if (node.locals) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b47b6cf94207c..d07166d1381f7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3848,7 +3848,11 @@ namespace ts { resolvedTrueType?: Type; resolvedFalseType?: Type; /* @internal */ + resolvedInferredTrueType?: Type; + /* @internal */ mapper?: TypeMapper; + /* @internal */ + combinedMapper?: TypeMapper; } // Type parameter substitution (TypeFlags.Substitution) From 228aff0cfb593c94df73052099d15e117aab383d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 28 Mar 2018 13:16:29 -0700 Subject: [PATCH 02/18] Add regression test --- .../cases/conformance/types/conditional/conditionalTypes1.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index e138798cb3c1e..4005e896ce124 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -215,6 +215,10 @@ type T50 = IsNever; // true type T51 = IsNever; // false type T52 = IsNever; // false +function f22(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // {} +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; From c0b96df41783b93f907de957e212128b6f634e97 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 28 Mar 2018 13:16:36 -0700 Subject: [PATCH 03/18] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 8 +- .../baselines/reference/conditionalTypes1.js | 8 + .../reference/conditionalTypes1.symbols | 597 +++++++++--------- .../reference/conditionalTypes1.types | 15 + 4 files changed, 334 insertions(+), 294 deletions(-) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index d96030fbecaed..b96ecf6254c8e 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -64,8 +64,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(159,5): error TS2 tests/cases/conformance/types/conditional/conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf'. Type 'string | number' is not assignable to type 'ZeroOf'. Type 'string' is not assignable to type 'ZeroOf'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(255,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(280,43): error TS2322: Type 'T95' is not assignable to type 'T94'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(259,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(284,43): error TS2322: Type 'T95' is not assignable to type 'T94'. Type 'boolean' is not assignable to type 'true'. @@ -370,6 +370,10 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(280,43): error TS type T51 = IsNever; // false type T52 = IsNever; // false + function f22(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // {} + } + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index b7eca66f0d5e5..109cf11b88a45 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -213,6 +213,10 @@ type T50 = IsNever; // true type T51 = IsNever; // false type T52 = IsNever; // false +function f22(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // {} +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; @@ -398,6 +402,9 @@ function f21(x, y) { x = y; // Error y = x; // Error } +function f22(x) { + var e = x[0]; // {} +} var convert = function (value) { return value; }; var convert2 = function (value) { return value; }; function f31() { @@ -590,6 +597,7 @@ declare type IsNever = [T] extends [never] ? true : false; declare type T50 = IsNever; declare type T51 = IsNever; declare type T52 = IsNever; +declare function f22(x: T extends (infer U)[] ? U[] : never): void; declare type Eq = T extends U ? U extends T ? true : false : false; declare type T60 = Eq; declare type T61 = Eq; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index bc64848213d98..6a59d7da9db64 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -819,475 +819,488 @@ type T52 = IsNever; // false >T52 : Symbol(T52, Decl(conditionalTypes1.ts, 211, 27)) >IsNever : Symbol(IsNever, Decl(conditionalTypes1.ts, 206, 47)) +function f22(x: T extends (infer U)[] ? U[] : never) { +>f22 : Symbol(f22, Decl(conditionalTypes1.ts, 212, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 13)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 214, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 35)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 35)) + + let e = x[0]; // {} +>e : Symbol(e, Decl(conditionalTypes1.ts, 215, 7)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 214, 16)) +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 216, 8)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 216, 10)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 216, 8)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 216, 10)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 216, 10)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 216, 8)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) type T60 = Eq; // true ->T60 : Symbol(T60, Decl(conditionalTypes1.ts, 216, 65)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) +>T60 : Symbol(T60, Decl(conditionalTypes1.ts, 220, 65)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) type T61 = Eq; // false ->T61 : Symbol(T61, Decl(conditionalTypes1.ts, 217, 26)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) +>T61 : Symbol(T61, Decl(conditionalTypes1.ts, 221, 26)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) type T62 = Eq; // false ->T62 : Symbol(T62, Decl(conditionalTypes1.ts, 218, 27)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) +>T62 : Symbol(T62, Decl(conditionalTypes1.ts, 222, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) type T63 = Eq; // true ->T63 : Symbol(T63, Decl(conditionalTypes1.ts, 219, 27)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) +>T63 : Symbol(T63, Decl(conditionalTypes1.ts, 223, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) type Eq1 = Eq extends false ? false : true; ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 220, 28)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 222, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 222, 11)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 222, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 222, 11)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 226, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 226, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 226, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 226, 11)) type T70 = Eq1; // true ->T70 : Symbol(T70, Decl(conditionalTypes1.ts, 222, 55)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 220, 28)) +>T70 : Symbol(T70, Decl(conditionalTypes1.ts, 226, 55)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) type T71 = Eq1; // false ->T71 : Symbol(T71, Decl(conditionalTypes1.ts, 223, 27)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 220, 28)) +>T71 : Symbol(T71, Decl(conditionalTypes1.ts, 227, 27)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) type T72 = Eq1; // false ->T72 : Symbol(T72, Decl(conditionalTypes1.ts, 224, 28)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 220, 28)) +>T72 : Symbol(T72, Decl(conditionalTypes1.ts, 228, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) type T73 = Eq1; // true ->T73 : Symbol(T73, Decl(conditionalTypes1.ts, 225, 28)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 220, 28)) +>T73 : Symbol(T73, Decl(conditionalTypes1.ts, 229, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) type Eq2 = Eq extends true ? true : false; ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 226, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 228, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 228, 11)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 212, 24)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 228, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 228, 11)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 232, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 232, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 232, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 232, 11)) type T80 = Eq2; // true ->T80 : Symbol(T80, Decl(conditionalTypes1.ts, 228, 54)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 226, 29)) +>T80 : Symbol(T80, Decl(conditionalTypes1.ts, 232, 54)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) type T81 = Eq2; // false ->T81 : Symbol(T81, Decl(conditionalTypes1.ts, 229, 27)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 226, 29)) +>T81 : Symbol(T81, Decl(conditionalTypes1.ts, 233, 27)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) type T82 = Eq2; // false ->T82 : Symbol(T82, Decl(conditionalTypes1.ts, 230, 28)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 226, 29)) +>T82 : Symbol(T82, Decl(conditionalTypes1.ts, 234, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) type T83 = Eq2; // true ->T83 : Symbol(T83, Decl(conditionalTypes1.ts, 231, 28)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 226, 29)) +>T83 : Symbol(T83, Decl(conditionalTypes1.ts, 235, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) // Repro from #21756 type Foo = T extends string ? boolean : number; ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 236, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 236, 9)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) type Bar = T extends string ? boolean : number; ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 236, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 237, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 237, 9)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 241, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 241, 9)) const convert = (value: Foo): Bar => value; ->convert : Symbol(convert, Decl(conditionalTypes1.ts, 238, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 238, 17)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 238, 20)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 238, 17)) ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 236, 50)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 238, 17)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 238, 20)) +>convert : Symbol(convert, Decl(conditionalTypes1.ts, 242, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 242, 20)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 242, 20)) type Baz = Foo; ->Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 238, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) +>Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 242, 52)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) const convert2 = (value: Foo): Baz => value; ->convert2 : Symbol(convert2, Decl(conditionalTypes1.ts, 241, 5)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 241, 18)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 241, 21)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 241, 18)) ->Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 238, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 241, 18)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 241, 21)) +>convert2 : Symbol(convert2, Decl(conditionalTypes1.ts, 245, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 245, 21)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) +>Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 242, 52)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 245, 21)) function f31() { ->f31 : Symbol(f31, Decl(conditionalTypes1.ts, 241, 53)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 243, 13)) +>f31 : Symbol(f31, Decl(conditionalTypes1.ts, 245, 53)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) type T1 = T extends string ? boolean : number; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 243, 19)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 243, 13)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 247, 19)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) type T2 = T extends string ? boolean : number; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 244, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 243, 13)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 248, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) var x: T1; ->x : Symbol(x, Decl(conditionalTypes1.ts, 246, 7), Decl(conditionalTypes1.ts, 247, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 243, 19)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 250, 7), Decl(conditionalTypes1.ts, 251, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 247, 19)) var x: T2; ->x : Symbol(x, Decl(conditionalTypes1.ts, 246, 7), Decl(conditionalTypes1.ts, 247, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 244, 50)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 250, 7), Decl(conditionalTypes1.ts, 251, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 248, 50)) } function f32() { ->f32 : Symbol(f32, Decl(conditionalTypes1.ts, 248, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 250, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 250, 15)) +>f32 : Symbol(f32, Decl(conditionalTypes1.ts, 252, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) type T1 = T & U extends string ? boolean : number; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 250, 22)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 250, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 250, 15)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 254, 22)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) type T2 = Foo; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 251, 54)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 250, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 250, 15)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 255, 54)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) var z: T1; ->z : Symbol(z, Decl(conditionalTypes1.ts, 253, 7), Decl(conditionalTypes1.ts, 254, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 250, 22)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 257, 7), Decl(conditionalTypes1.ts, 258, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 254, 22)) var z: T2; // Error, T2 is distributive, T1 isn't ->z : Symbol(z, Decl(conditionalTypes1.ts, 253, 7), Decl(conditionalTypes1.ts, 254, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 251, 54)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 257, 7), Decl(conditionalTypes1.ts, 258, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 255, 54)) } function f33() { ->f33 : Symbol(f33, Decl(conditionalTypes1.ts, 255, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 257, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 257, 15)) +>f33 : Symbol(f33, Decl(conditionalTypes1.ts, 259, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) type T1 = Foo; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 257, 22)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 232, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 257, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 257, 15)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 261, 22)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) type T2 = Bar; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 258, 25)) ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 236, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 257, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 257, 15)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 262, 25)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) var z: T1; ->z : Symbol(z, Decl(conditionalTypes1.ts, 260, 7), Decl(conditionalTypes1.ts, 261, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 257, 22)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 264, 7), Decl(conditionalTypes1.ts, 265, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 261, 22)) var z: T2; ->z : Symbol(z, Decl(conditionalTypes1.ts, 260, 7), Decl(conditionalTypes1.ts, 261, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 258, 25)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 264, 7), Decl(conditionalTypes1.ts, 265, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 262, 25)) } // Repro from #21823 type T90 = T extends 0 ? 0 : () => 0; ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 262, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 266, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 266, 9)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 270, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 270, 9)) type T91 = T extends 0 ? 0 : () => 0; ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 266, 40)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 267, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 267, 9)) - -const f40 = (a: T90): T91 => a; ->f40 : Symbol(f40, Decl(conditionalTypes1.ts, 268, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 268, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 268, 16)) ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 262, 1)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 268, 13)) ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 266, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 268, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 268, 16)) - -const f41 = (a: T91): T90 => a; ->f41 : Symbol(f41, Decl(conditionalTypes1.ts, 269, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 269, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 269, 16)) ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 266, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 269, 13)) ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 262, 1)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 269, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 269, 16)) - -type T92 = T extends () => 0 ? () => 1 : () => 2; ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 269, 40)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) >T : Symbol(T, Decl(conditionalTypes1.ts, 271, 9)) >T : Symbol(T, Decl(conditionalTypes1.ts, 271, 9)) -type T93 = T extends () => 0 ? () => 1 : () => 2; ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 271, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 272, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 272, 9)) +const f40 = (a: T90): T91 => a; +>f40 : Symbol(f40, Decl(conditionalTypes1.ts, 272, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 272, 16)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 272, 16)) -const f42 = (a: T92): T93 => a; ->f42 : Symbol(f42, Decl(conditionalTypes1.ts, 273, 5)) +const f41 = (a: T91): T90 => a; +>f41 : Symbol(f41, Decl(conditionalTypes1.ts, 273, 5)) >U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) >a : Symbol(a, Decl(conditionalTypes1.ts, 273, 16)) ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 269, 40)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) >U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 271, 52)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) >U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) >a : Symbol(a, Decl(conditionalTypes1.ts, 273, 16)) -const f43 = (a: T93): T92 => a; ->f43 : Symbol(f43, Decl(conditionalTypes1.ts, 274, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 274, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 274, 16)) ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 271, 52)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 274, 13)) ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 269, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 274, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 274, 16)) +type T92 = T extends () => 0 ? () => 1 : () => 2; +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 275, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 275, 9)) -type T94 = T extends string ? true : 42; ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 274, 40)) +type T93 = T extends () => 0 ? () => 1 : () => 2; +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) >T : Symbol(T, Decl(conditionalTypes1.ts, 276, 9)) >T : Symbol(T, Decl(conditionalTypes1.ts, 276, 9)) -type T95 = T extends string ? boolean : number; ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 276, 43)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 277, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 277, 9)) +const f42 = (a: T92): T93 => a; +>f42 : Symbol(f42, Decl(conditionalTypes1.ts, 277, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 277, 16)) +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 277, 16)) -const f44 = (value: T94): T95 => value; ->f44 : Symbol(f44, Decl(conditionalTypes1.ts, 278, 5)) +const f43 = (a: T93): T92 => a; +>f43 : Symbol(f43, Decl(conditionalTypes1.ts, 278, 5)) >U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 278, 16)) ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 274, 40)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 278, 16)) +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) >U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 276, 43)) +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) >U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 278, 16)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 278, 16)) + +type T94 = T extends string ? true : 42; +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 280, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 280, 9)) + +type T95 = T extends string ? boolean : number; +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 281, 9)) + +const f44 = (value: T94): T95 => value; +>f44 : Symbol(f44, Decl(conditionalTypes1.ts, 282, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 282, 16)) +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 282, 16)) const f45 = (value: T95): T94 => value; // Error ->f45 : Symbol(f45, Decl(conditionalTypes1.ts, 279, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 279, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 279, 16)) ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 276, 43)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 279, 13)) ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 274, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 279, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 279, 16)) +>f45 : Symbol(f45, Decl(conditionalTypes1.ts, 283, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 283, 16)) +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 283, 16)) // Repro from #21863 function f50() { ->f50 : Symbol(f50, Decl(conditionalTypes1.ts, 279, 48)) +>f50 : Symbol(f50, Decl(conditionalTypes1.ts, 283, 48)) type Eq = T extends U ? U extends T ? true : false : false; ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 283, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 284, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 284, 14)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 284, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 284, 14)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 284, 14)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 284, 12)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) type If = S extends false ? U : T; ->If : Symbol(If, Decl(conditionalTypes1.ts, 284, 69)) ->S : Symbol(S, Decl(conditionalTypes1.ts, 285, 12)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 285, 14)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 285, 17)) ->S : Symbol(S, Decl(conditionalTypes1.ts, 285, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 285, 17)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 285, 14)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) +>S : Symbol(S, Decl(conditionalTypes1.ts, 289, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 14)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 17)) +>S : Symbol(S, Decl(conditionalTypes1.ts, 289, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 289, 17)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 289, 14)) type Omit = { [P in keyof T]: If, never, P>; }[keyof T]; ->Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 285, 47)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 286, 14)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 286, 37)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 286, 14)) ->If : Symbol(If, Decl(conditionalTypes1.ts, 284, 69)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 283, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 286, 14)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 286, 37)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 286, 37)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 286, 14)) +>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 289, 47)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) type Omit2 = { [P in keyof T]: If, never, P>; }[keyof T]; ->Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 286, 94)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 287, 15)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 287, 32)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 287, 49)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 287, 15)) ->If : Symbol(If, Decl(conditionalTypes1.ts, 284, 69)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 283, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 287, 15)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 287, 49)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 287, 32)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 287, 49)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 287, 15)) +>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 290, 94)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 291, 32)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 291, 32)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) type A = Omit<{ a: void; b: never; }>; // 'a' ->A : Symbol(A, Decl(conditionalTypes1.ts, 287, 102)) ->Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 285, 47)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 288, 19)) ->b : Symbol(b, Decl(conditionalTypes1.ts, 288, 28)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 291, 102)) +>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 289, 47)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 292, 19)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 292, 28)) type B = Omit2<{ a: void; b: never; }>; // 'a' ->B : Symbol(B, Decl(conditionalTypes1.ts, 288, 42)) ->Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 286, 94)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 289, 20)) ->b : Symbol(b, Decl(conditionalTypes1.ts, 289, 29)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 292, 42)) +>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 290, 94)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 293, 20)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 293, 29)) } // Repro from #21862 type OldDiff = ( ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 290, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 294, 30)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 298, 30)) & { [P in T]: P; } ->P : Symbol(P, Decl(conditionalTypes1.ts, 295, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 295, 9)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 299, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 299, 9)) & { [P in U]: never; } ->P : Symbol(P, Decl(conditionalTypes1.ts, 296, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 294, 30)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 300, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 298, 30)) & { [x: string]: never; } ->x : Symbol(x, Decl(conditionalTypes1.ts, 297, 9)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 301, 9)) )[T]; ->T : Symbol(T, Decl(conditionalTypes1.ts, 294, 13)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) type NewDiff = T extends U ? never : T; ->NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 298, 5)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 299, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 299, 15)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 299, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 299, 15)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 299, 13)) +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 302, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 303, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 303, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) interface A { ->A : Symbol(A, Decl(conditionalTypes1.ts, 299, 45)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) a: 'a'; ->a : Symbol(A.a, Decl(conditionalTypes1.ts, 300, 13)) +>a : Symbol(A.a, Decl(conditionalTypes1.ts, 304, 13)) } interface B1 extends A { ->B1 : Symbol(B1, Decl(conditionalTypes1.ts, 302, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 299, 45)) +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 306, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) b: 'b'; ->b : Symbol(B1.b, Decl(conditionalTypes1.ts, 303, 24)) +>b : Symbol(B1.b, Decl(conditionalTypes1.ts, 307, 24)) c: OldDiff; ->c : Symbol(B1.c, Decl(conditionalTypes1.ts, 304, 11)) ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 290, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 299, 45)) +>c : Symbol(B1.c, Decl(conditionalTypes1.ts, 308, 11)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) } interface B2 extends A { ->B2 : Symbol(B2, Decl(conditionalTypes1.ts, 306, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 299, 45)) +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 310, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) b: 'b'; ->b : Symbol(B2.b, Decl(conditionalTypes1.ts, 307, 24)) +>b : Symbol(B2.b, Decl(conditionalTypes1.ts, 311, 24)) c: NewDiff; ->c : Symbol(B2.c, Decl(conditionalTypes1.ts, 308, 11)) ->NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 298, 5)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 299, 45)) +>c : Symbol(B2.c, Decl(conditionalTypes1.ts, 312, 11)) +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 302, 5)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) } type c1 = B1['c']; // 'c' | 'b' ->c1 : Symbol(c1, Decl(conditionalTypes1.ts, 310, 1)) ->B1 : Symbol(B1, Decl(conditionalTypes1.ts, 302, 1)) +>c1 : Symbol(c1, Decl(conditionalTypes1.ts, 314, 1)) +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 306, 1)) type c2 = B2['c']; // 'c' | 'b' ->c2 : Symbol(c2, Decl(conditionalTypes1.ts, 311, 18)) ->B2 : Symbol(B2, Decl(conditionalTypes1.ts, 306, 1)) +>c2 : Symbol(c2, Decl(conditionalTypes1.ts, 315, 18)) +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 310, 1)) // Repro from #21929 type NonFooKeys1 = OldDiff; ->NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 312, 18)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 316, 17)) ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 290, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 316, 17)) +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 316, 18)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 320, 17)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 320, 17)) type NonFooKeys2 = Exclude; ->NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 316, 61)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 317, 17)) +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 320, 61)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 321, 17)) >Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 317, 17)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 321, 17)) type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" ->Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 317, 61)) ->NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 312, 18)) ->foo : Symbol(foo, Decl(conditionalTypes1.ts, 319, 26)) ->bar : Symbol(bar, Decl(conditionalTypes1.ts, 319, 33)) ->baz : Symbol(baz, Decl(conditionalTypes1.ts, 319, 41)) +>Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 321, 61)) +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 316, 18)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 323, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 323, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 323, 41)) type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" ->Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 319, 51)) ->NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 316, 61)) ->foo : Symbol(foo, Decl(conditionalTypes1.ts, 320, 26)) ->bar : Symbol(bar, Decl(conditionalTypes1.ts, 320, 33)) ->baz : Symbol(baz, Decl(conditionalTypes1.ts, 320, 41)) +>Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 323, 51)) +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 320, 61)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 324, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 324, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 324, 41)) // Repro from #21729 interface Foo2 { foo: string; } ->Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 320, 51)) ->foo : Symbol(Foo2.foo, Decl(conditionalTypes1.ts, 324, 16)) +>Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 324, 51)) +>foo : Symbol(Foo2.foo, Decl(conditionalTypes1.ts, 328, 16)) interface Bar2 { bar: string; } ->Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 324, 31)) ->bar : Symbol(Bar2.bar, Decl(conditionalTypes1.ts, 325, 16)) +>Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 328, 31)) +>bar : Symbol(Bar2.bar, Decl(conditionalTypes1.ts, 329, 16)) type FooBar = Foo2 | Bar2; ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 325, 31)) ->Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 320, 51)) ->Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 324, 31)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) +>Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 324, 51)) +>Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 328, 31)) declare interface ExtractFooBar { } ->ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 326, 26)) ->FB : Symbol(FB, Decl(conditionalTypes1.ts, 327, 32)) ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 325, 31)) +>ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 330, 26)) +>FB : Symbol(FB, Decl(conditionalTypes1.ts, 331, 32)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) type Extracted = { ->Extracted : Symbol(Extracted, Decl(conditionalTypes1.ts, 327, 54)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 329, 15)) +>Extracted : Symbol(Extracted, Decl(conditionalTypes1.ts, 331, 54)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; ->K : Symbol(K, Decl(conditionalTypes1.ts, 330, 5)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 329, 15)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 329, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 330, 5)) ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 325, 31)) ->ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 326, 26)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 329, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 330, 5)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 329, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 330, 5)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) +>ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 330, 26)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) } diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 01fef85dfcb6d..0d7624b07c8bf 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -926,6 +926,21 @@ type T52 = IsNever; // false >T52 : false >IsNever : IsNever +function f22(x: T extends (infer U)[] ? U[] : never) { +>f22 : (x: T extends infer U[] ? U[] : never) => void +>T : T +>x : T extends infer U[] ? U[] : never +>T : T +>U : U +>U : U + + let e = x[0]; // {} +>e : {} +>x[0] : {} +>x : T extends infer U[] ? U[] : never +>0 : 0 +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; From 8f25748334f7537681407841a1ea99d87d3f121d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 28 Mar 2018 15:21:29 -0700 Subject: [PATCH 04/18] Add another test --- .../cases/conformance/types/conditional/conditionalTypes1.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index 4005e896ce124..8aa524ba8183e 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -219,6 +219,10 @@ function f22(x: T extends (infer U)[] ? U[] : never) { let e = x[0]; // {} } +function f23(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // string +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; From ebadc1dc8a84799111df82a21d7b8ba0be2bcadf Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 28 Mar 2018 15:21:36 -0700 Subject: [PATCH 05/18] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 8 +- .../baselines/reference/conditionalTypes1.js | 8 + .../reference/conditionalTypes1.symbols | 597 +++++++++--------- .../reference/conditionalTypes1.types | 15 + 4 files changed, 334 insertions(+), 294 deletions(-) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index b96ecf6254c8e..de06eeb832bf1 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -64,8 +64,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(159,5): error TS2 tests/cases/conformance/types/conditional/conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf'. Type 'string | number' is not assignable to type 'ZeroOf'. Type 'string' is not assignable to type 'ZeroOf'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(259,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(284,43): error TS2322: Type 'T95' is not assignable to type 'T94'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(263,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'z' must be of type 'T1', but here has type 'Foo'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS2322: Type 'T95' is not assignable to type 'T94'. Type 'boolean' is not assignable to type 'true'. @@ -374,6 +374,10 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(284,43): error TS let e = x[0]; // {} } + function f23(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // string + } + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 109cf11b88a45..1be708fed0125 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -217,6 +217,10 @@ function f22(x: T extends (infer U)[] ? U[] : never) { let e = x[0]; // {} } +function f23(x: T extends (infer U)[] ? U[] : never) { + let e = x[0]; // string +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; @@ -405,6 +409,9 @@ function f21(x, y) { function f22(x) { var e = x[0]; // {} } +function f23(x) { + var e = x[0]; // string +} var convert = function (value) { return value; }; var convert2 = function (value) { return value; }; function f31() { @@ -598,6 +605,7 @@ declare type T50 = IsNever; declare type T51 = IsNever; declare type T52 = IsNever; declare function f22(x: T extends (infer U)[] ? U[] : never): void; +declare function f23(x: T extends (infer U)[] ? U[] : never): void; declare type Eq = T extends U ? U extends T ? true : false : false; declare type T60 = Eq; declare type T61 = Eq; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index 6a59d7da9db64..ae13ff75913c0 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -832,475 +832,488 @@ function f22(x: T extends (infer U)[] ? U[] : never) { >x : Symbol(x, Decl(conditionalTypes1.ts, 214, 16)) } +function f23(x: T extends (infer U)[] ? U[] : never) { +>f23 : Symbol(f23, Decl(conditionalTypes1.ts, 216, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 218, 13)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 218, 33)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 218, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 218, 52)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 218, 52)) + + let e = x[0]; // string +>e : Symbol(e, Decl(conditionalTypes1.ts, 219, 7)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 218, 33)) +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 220, 10)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 220, 8)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 224, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 224, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 224, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 224, 10)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 224, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 224, 8)) type T60 = Eq; // true ->T60 : Symbol(T60, Decl(conditionalTypes1.ts, 220, 65)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T60 : Symbol(T60, Decl(conditionalTypes1.ts, 224, 65)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) type T61 = Eq; // false ->T61 : Symbol(T61, Decl(conditionalTypes1.ts, 221, 26)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T61 : Symbol(T61, Decl(conditionalTypes1.ts, 225, 26)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) type T62 = Eq; // false ->T62 : Symbol(T62, Decl(conditionalTypes1.ts, 222, 27)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T62 : Symbol(T62, Decl(conditionalTypes1.ts, 226, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) type T63 = Eq; // true ->T63 : Symbol(T63, Decl(conditionalTypes1.ts, 223, 27)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) +>T63 : Symbol(T63, Decl(conditionalTypes1.ts, 227, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) type Eq1 = Eq extends false ? false : true; ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 226, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 226, 11)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 226, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 226, 11)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 228, 28)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 230, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 230, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 230, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 230, 11)) type T70 = Eq1; // true ->T70 : Symbol(T70, Decl(conditionalTypes1.ts, 226, 55)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) +>T70 : Symbol(T70, Decl(conditionalTypes1.ts, 230, 55)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 228, 28)) type T71 = Eq1; // false ->T71 : Symbol(T71, Decl(conditionalTypes1.ts, 227, 27)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) +>T71 : Symbol(T71, Decl(conditionalTypes1.ts, 231, 27)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 228, 28)) type T72 = Eq1; // false ->T72 : Symbol(T72, Decl(conditionalTypes1.ts, 228, 28)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) +>T72 : Symbol(T72, Decl(conditionalTypes1.ts, 232, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 228, 28)) type T73 = Eq1; // true ->T73 : Symbol(T73, Decl(conditionalTypes1.ts, 229, 28)) ->Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 224, 28)) +>T73 : Symbol(T73, Decl(conditionalTypes1.ts, 233, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 228, 28)) type Eq2 = Eq extends true ? true : false; ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 232, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 232, 11)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 216, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 232, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 232, 11)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 234, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 236, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 236, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 220, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 236, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 236, 11)) type T80 = Eq2; // true ->T80 : Symbol(T80, Decl(conditionalTypes1.ts, 232, 54)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) +>T80 : Symbol(T80, Decl(conditionalTypes1.ts, 236, 54)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 234, 29)) type T81 = Eq2; // false ->T81 : Symbol(T81, Decl(conditionalTypes1.ts, 233, 27)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) +>T81 : Symbol(T81, Decl(conditionalTypes1.ts, 237, 27)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 234, 29)) type T82 = Eq2; // false ->T82 : Symbol(T82, Decl(conditionalTypes1.ts, 234, 28)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) +>T82 : Symbol(T82, Decl(conditionalTypes1.ts, 238, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 234, 29)) type T83 = Eq2; // true ->T83 : Symbol(T83, Decl(conditionalTypes1.ts, 235, 28)) ->Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 230, 29)) +>T83 : Symbol(T83, Decl(conditionalTypes1.ts, 239, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 234, 29)) // Repro from #21756 type Foo = T extends string ? boolean : number; ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 240, 9)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) type Bar = T extends string ? boolean : number; ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 241, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 241, 9)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 244, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 245, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 245, 9)) const convert = (value: Foo): Bar => value; ->convert : Symbol(convert, Decl(conditionalTypes1.ts, 242, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 242, 20)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 242, 17)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 242, 20)) +>convert : Symbol(convert, Decl(conditionalTypes1.ts, 246, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 246, 17)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 246, 20)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 246, 17)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 244, 50)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 246, 17)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 246, 20)) type Baz = Foo; ->Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 242, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 244, 9)) +>Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 246, 52)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 248, 9)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 248, 9)) const convert2 = (value: Foo): Baz => value; ->convert2 : Symbol(convert2, Decl(conditionalTypes1.ts, 245, 5)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 245, 21)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) ->Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 242, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 245, 18)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 245, 21)) +>convert2 : Symbol(convert2, Decl(conditionalTypes1.ts, 249, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 249, 18)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 249, 21)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 249, 18)) +>Baz : Symbol(Baz, Decl(conditionalTypes1.ts, 246, 52)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 249, 18)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 249, 21)) function f31() { ->f31 : Symbol(f31, Decl(conditionalTypes1.ts, 245, 53)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) +>f31 : Symbol(f31, Decl(conditionalTypes1.ts, 249, 53)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 251, 13)) type T1 = T extends string ? boolean : number; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 247, 19)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 251, 19)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 251, 13)) type T2 = T extends string ? boolean : number; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 248, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 247, 13)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 252, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 251, 13)) var x: T1; ->x : Symbol(x, Decl(conditionalTypes1.ts, 250, 7), Decl(conditionalTypes1.ts, 251, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 247, 19)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 254, 7), Decl(conditionalTypes1.ts, 255, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 251, 19)) var x: T2; ->x : Symbol(x, Decl(conditionalTypes1.ts, 250, 7), Decl(conditionalTypes1.ts, 251, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 248, 50)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 254, 7), Decl(conditionalTypes1.ts, 255, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 252, 50)) } function f32() { ->f32 : Symbol(f32, Decl(conditionalTypes1.ts, 252, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) +>f32 : Symbol(f32, Decl(conditionalTypes1.ts, 256, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 258, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 258, 15)) type T1 = T & U extends string ? boolean : number; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 254, 22)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 258, 22)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 258, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 258, 15)) type T2 = Foo; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 255, 54)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 254, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 254, 15)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 259, 54)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 258, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 258, 15)) var z: T1; ->z : Symbol(z, Decl(conditionalTypes1.ts, 257, 7), Decl(conditionalTypes1.ts, 258, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 254, 22)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 261, 7), Decl(conditionalTypes1.ts, 262, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 258, 22)) var z: T2; // Error, T2 is distributive, T1 isn't ->z : Symbol(z, Decl(conditionalTypes1.ts, 257, 7), Decl(conditionalTypes1.ts, 258, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 255, 54)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 261, 7), Decl(conditionalTypes1.ts, 262, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 259, 54)) } function f33() { ->f33 : Symbol(f33, Decl(conditionalTypes1.ts, 259, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) +>f33 : Symbol(f33, Decl(conditionalTypes1.ts, 263, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 265, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 265, 15)) type T1 = Foo; ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 261, 22)) ->Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 236, 29)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 265, 22)) +>Foo : Symbol(Foo, Decl(conditionalTypes1.ts, 240, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 265, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 265, 15)) type T2 = Bar; ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 262, 25)) ->Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 240, 50)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 261, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 261, 15)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 266, 25)) +>Bar : Symbol(Bar, Decl(conditionalTypes1.ts, 244, 50)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 265, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 265, 15)) var z: T1; ->z : Symbol(z, Decl(conditionalTypes1.ts, 264, 7), Decl(conditionalTypes1.ts, 265, 7)) ->T1 : Symbol(T1, Decl(conditionalTypes1.ts, 261, 22)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 268, 7), Decl(conditionalTypes1.ts, 269, 7)) +>T1 : Symbol(T1, Decl(conditionalTypes1.ts, 265, 22)) var z: T2; ->z : Symbol(z, Decl(conditionalTypes1.ts, 264, 7), Decl(conditionalTypes1.ts, 265, 7)) ->T2 : Symbol(T2, Decl(conditionalTypes1.ts, 262, 25)) +>z : Symbol(z, Decl(conditionalTypes1.ts, 268, 7), Decl(conditionalTypes1.ts, 269, 7)) +>T2 : Symbol(T2, Decl(conditionalTypes1.ts, 266, 25)) } // Repro from #21823 type T90 = T extends 0 ? 0 : () => 0; ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 270, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 270, 9)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 270, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 274, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 274, 9)) type T91 = T extends 0 ? 0 : () => 0; ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 271, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 271, 9)) - -const f40 = (a: T90): T91 => a; ->f40 : Symbol(f40, Decl(conditionalTypes1.ts, 272, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 272, 16)) ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 272, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 272, 16)) - -const f41 = (a: T91): T90 => a; ->f41 : Symbol(f41, Decl(conditionalTypes1.ts, 273, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 273, 16)) ->T91 : Symbol(T91, Decl(conditionalTypes1.ts, 270, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) ->T90 : Symbol(T90, Decl(conditionalTypes1.ts, 266, 1)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 273, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 273, 16)) - -type T92 = T extends () => 0 ? () => 1 : () => 2; ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 274, 40)) >T : Symbol(T, Decl(conditionalTypes1.ts, 275, 9)) >T : Symbol(T, Decl(conditionalTypes1.ts, 275, 9)) -type T93 = T extends () => 0 ? () => 1 : () => 2; ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 276, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 276, 9)) +const f40 = (a: T90): T91 => a; +>f40 : Symbol(f40, Decl(conditionalTypes1.ts, 276, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 276, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 276, 16)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 270, 1)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 276, 13)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 274, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 276, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 276, 16)) -const f42 = (a: T92): T93 => a; ->f42 : Symbol(f42, Decl(conditionalTypes1.ts, 277, 5)) +const f41 = (a: T91): T90 => a; +>f41 : Symbol(f41, Decl(conditionalTypes1.ts, 277, 5)) >U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) >a : Symbol(a, Decl(conditionalTypes1.ts, 277, 16)) ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) +>T91 : Symbol(T91, Decl(conditionalTypes1.ts, 274, 40)) >U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) +>T90 : Symbol(T90, Decl(conditionalTypes1.ts, 270, 1)) >U : Symbol(U, Decl(conditionalTypes1.ts, 277, 13)) >a : Symbol(a, Decl(conditionalTypes1.ts, 277, 16)) -const f43 = (a: T93): T92 => a; ->f43 : Symbol(f43, Decl(conditionalTypes1.ts, 278, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 278, 16)) ->T93 : Symbol(T93, Decl(conditionalTypes1.ts, 275, 52)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->T92 : Symbol(T92, Decl(conditionalTypes1.ts, 273, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 278, 13)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 278, 16)) +type T92 = T extends () => 0 ? () => 1 : () => 2; +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 277, 40)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 279, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 279, 9)) -type T94 = T extends string ? true : 42; ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) +type T93 = T extends () => 0 ? () => 1 : () => 2; +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 279, 52)) >T : Symbol(T, Decl(conditionalTypes1.ts, 280, 9)) >T : Symbol(T, Decl(conditionalTypes1.ts, 280, 9)) -type T95 = T extends string ? boolean : number; ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 281, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 281, 9)) +const f42 = (a: T92): T93 => a; +>f42 : Symbol(f42, Decl(conditionalTypes1.ts, 281, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 281, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 281, 16)) +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 277, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 281, 13)) +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 279, 52)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 281, 13)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 281, 16)) -const f44 = (value: T94): T95 => value; ->f44 : Symbol(f44, Decl(conditionalTypes1.ts, 282, 5)) +const f43 = (a: T93): T92 => a; +>f43 : Symbol(f43, Decl(conditionalTypes1.ts, 282, 5)) >U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 282, 16)) ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 282, 16)) +>T93 : Symbol(T93, Decl(conditionalTypes1.ts, 279, 52)) >U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) +>T92 : Symbol(T92, Decl(conditionalTypes1.ts, 277, 40)) >U : Symbol(U, Decl(conditionalTypes1.ts, 282, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 282, 16)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 282, 16)) + +type T94 = T extends string ? true : 42; +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 282, 40)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 284, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 284, 9)) + +type T95 = T extends string ? boolean : number; +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 284, 43)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 285, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 285, 9)) + +const f44 = (value: T94): T95 => value; +>f44 : Symbol(f44, Decl(conditionalTypes1.ts, 286, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 286, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 286, 16)) +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 282, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 286, 13)) +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 284, 43)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 286, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 286, 16)) const f45 = (value: T95): T94 => value; // Error ->f45 : Symbol(f45, Decl(conditionalTypes1.ts, 283, 5)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 283, 16)) ->T95 : Symbol(T95, Decl(conditionalTypes1.ts, 280, 43)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) ->T94 : Symbol(T94, Decl(conditionalTypes1.ts, 278, 40)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 283, 13)) ->value : Symbol(value, Decl(conditionalTypes1.ts, 283, 16)) +>f45 : Symbol(f45, Decl(conditionalTypes1.ts, 287, 5)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 287, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 287, 16)) +>T95 : Symbol(T95, Decl(conditionalTypes1.ts, 284, 43)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 287, 13)) +>T94 : Symbol(T94, Decl(conditionalTypes1.ts, 282, 40)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 287, 13)) +>value : Symbol(value, Decl(conditionalTypes1.ts, 287, 16)) // Repro from #21863 function f50() { ->f50 : Symbol(f50, Decl(conditionalTypes1.ts, 283, 48)) +>f50 : Symbol(f50, Decl(conditionalTypes1.ts, 287, 48)) type Eq = T extends U ? U extends T ? true : false : false; ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 288, 14)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 288, 12)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 291, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 292, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 292, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 292, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 292, 14)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 292, 14)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 292, 12)) type If = S extends false ? U : T; ->If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) ->S : Symbol(S, Decl(conditionalTypes1.ts, 289, 12)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 289, 14)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 289, 17)) ->S : Symbol(S, Decl(conditionalTypes1.ts, 289, 12)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 289, 17)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 289, 14)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 292, 69)) +>S : Symbol(S, Decl(conditionalTypes1.ts, 293, 12)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 293, 14)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 293, 17)) +>S : Symbol(S, Decl(conditionalTypes1.ts, 293, 12)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 293, 17)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 293, 14)) type Omit = { [P in keyof T]: If, never, P>; }[keyof T]; ->Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 289, 47)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) ->If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 290, 37)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 290, 14)) +>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 293, 47)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 14)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 294, 37)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 14)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 292, 69)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 291, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 14)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 294, 37)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 294, 37)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 294, 14)) type Omit2 = { [P in keyof T]: If, never, P>; }[keyof T]; ->Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 290, 94)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 291, 32)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) ->If : Symbol(If, Decl(conditionalTypes1.ts, 288, 69)) ->Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 287, 16)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 291, 32)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 291, 49)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 291, 15)) +>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 294, 94)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 295, 15)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 295, 32)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 295, 49)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 295, 15)) +>If : Symbol(If, Decl(conditionalTypes1.ts, 292, 69)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 291, 16)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 295, 15)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 295, 49)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 295, 32)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 295, 49)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 295, 15)) type A = Omit<{ a: void; b: never; }>; // 'a' ->A : Symbol(A, Decl(conditionalTypes1.ts, 291, 102)) ->Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 289, 47)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 292, 19)) ->b : Symbol(b, Decl(conditionalTypes1.ts, 292, 28)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 295, 102)) +>Omit : Symbol(Omit, Decl(conditionalTypes1.ts, 293, 47)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 296, 19)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 296, 28)) type B = Omit2<{ a: void; b: never; }>; // 'a' ->B : Symbol(B, Decl(conditionalTypes1.ts, 292, 42)) ->Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 290, 94)) ->a : Symbol(a, Decl(conditionalTypes1.ts, 293, 20)) ->b : Symbol(b, Decl(conditionalTypes1.ts, 293, 29)) +>B : Symbol(B, Decl(conditionalTypes1.ts, 296, 42)) +>Omit2 : Symbol(Omit2, Decl(conditionalTypes1.ts, 294, 94)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 297, 20)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 297, 29)) } // Repro from #21862 type OldDiff = ( ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 298, 30)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 298, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 302, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 302, 30)) & { [P in T]: P; } ->P : Symbol(P, Decl(conditionalTypes1.ts, 299, 9)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) ->P : Symbol(P, Decl(conditionalTypes1.ts, 299, 9)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 303, 9)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 302, 13)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 303, 9)) & { [P in U]: never; } ->P : Symbol(P, Decl(conditionalTypes1.ts, 300, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 298, 30)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 304, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 302, 30)) & { [x: string]: never; } ->x : Symbol(x, Decl(conditionalTypes1.ts, 301, 9)) +>x : Symbol(x, Decl(conditionalTypes1.ts, 305, 9)) )[T]; ->T : Symbol(T, Decl(conditionalTypes1.ts, 298, 13)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 302, 13)) type NewDiff = T extends U ? never : T; ->NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 302, 5)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 303, 15)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 303, 15)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 303, 13)) +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 306, 5)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 307, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 307, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 307, 13)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 307, 15)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 307, 13)) interface A { ->A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 307, 45)) a: 'a'; ->a : Symbol(A.a, Decl(conditionalTypes1.ts, 304, 13)) +>a : Symbol(A.a, Decl(conditionalTypes1.ts, 308, 13)) } interface B1 extends A { ->B1 : Symbol(B1, Decl(conditionalTypes1.ts, 306, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 310, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 307, 45)) b: 'b'; ->b : Symbol(B1.b, Decl(conditionalTypes1.ts, 307, 24)) +>b : Symbol(B1.b, Decl(conditionalTypes1.ts, 311, 24)) c: OldDiff; ->c : Symbol(B1.c, Decl(conditionalTypes1.ts, 308, 11)) ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) +>c : Symbol(B1.c, Decl(conditionalTypes1.ts, 312, 11)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 298, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 307, 45)) } interface B2 extends A { ->B2 : Symbol(B2, Decl(conditionalTypes1.ts, 310, 1)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 314, 1)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 307, 45)) b: 'b'; ->b : Symbol(B2.b, Decl(conditionalTypes1.ts, 311, 24)) +>b : Symbol(B2.b, Decl(conditionalTypes1.ts, 315, 24)) c: NewDiff; ->c : Symbol(B2.c, Decl(conditionalTypes1.ts, 312, 11)) ->NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 302, 5)) ->A : Symbol(A, Decl(conditionalTypes1.ts, 303, 45)) +>c : Symbol(B2.c, Decl(conditionalTypes1.ts, 316, 11)) +>NewDiff : Symbol(NewDiff, Decl(conditionalTypes1.ts, 306, 5)) +>A : Symbol(A, Decl(conditionalTypes1.ts, 307, 45)) } type c1 = B1['c']; // 'c' | 'b' ->c1 : Symbol(c1, Decl(conditionalTypes1.ts, 314, 1)) ->B1 : Symbol(B1, Decl(conditionalTypes1.ts, 306, 1)) +>c1 : Symbol(c1, Decl(conditionalTypes1.ts, 318, 1)) +>B1 : Symbol(B1, Decl(conditionalTypes1.ts, 310, 1)) type c2 = B2['c']; // 'c' | 'b' ->c2 : Symbol(c2, Decl(conditionalTypes1.ts, 315, 18)) ->B2 : Symbol(B2, Decl(conditionalTypes1.ts, 310, 1)) +>c2 : Symbol(c2, Decl(conditionalTypes1.ts, 319, 18)) +>B2 : Symbol(B2, Decl(conditionalTypes1.ts, 314, 1)) // Repro from #21929 type NonFooKeys1 = OldDiff; ->NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 316, 18)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 320, 17)) ->OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 294, 1)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 320, 17)) +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 320, 18)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 324, 17)) +>OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 298, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 324, 17)) type NonFooKeys2 = Exclude; ->NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 320, 61)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 321, 17)) +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 324, 61)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 325, 17)) >Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(conditionalTypes1.ts, 321, 17)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 325, 17)) type Test1 = NonFooKeys1<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" ->Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 321, 61)) ->NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 316, 18)) ->foo : Symbol(foo, Decl(conditionalTypes1.ts, 323, 26)) ->bar : Symbol(bar, Decl(conditionalTypes1.ts, 323, 33)) ->baz : Symbol(baz, Decl(conditionalTypes1.ts, 323, 41)) +>Test1 : Symbol(Test1, Decl(conditionalTypes1.ts, 325, 61)) +>NonFooKeys1 : Symbol(NonFooKeys1, Decl(conditionalTypes1.ts, 320, 18)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 327, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 327, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 327, 41)) type Test2 = NonFooKeys2<{foo: 1, bar: 2, baz: 3}>; // "bar" | "baz" ->Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 323, 51)) ->NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 320, 61)) ->foo : Symbol(foo, Decl(conditionalTypes1.ts, 324, 26)) ->bar : Symbol(bar, Decl(conditionalTypes1.ts, 324, 33)) ->baz : Symbol(baz, Decl(conditionalTypes1.ts, 324, 41)) +>Test2 : Symbol(Test2, Decl(conditionalTypes1.ts, 327, 51)) +>NonFooKeys2 : Symbol(NonFooKeys2, Decl(conditionalTypes1.ts, 324, 61)) +>foo : Symbol(foo, Decl(conditionalTypes1.ts, 328, 26)) +>bar : Symbol(bar, Decl(conditionalTypes1.ts, 328, 33)) +>baz : Symbol(baz, Decl(conditionalTypes1.ts, 328, 41)) // Repro from #21729 interface Foo2 { foo: string; } ->Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 324, 51)) ->foo : Symbol(Foo2.foo, Decl(conditionalTypes1.ts, 328, 16)) +>Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 328, 51)) +>foo : Symbol(Foo2.foo, Decl(conditionalTypes1.ts, 332, 16)) interface Bar2 { bar: string; } ->Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 328, 31)) ->bar : Symbol(Bar2.bar, Decl(conditionalTypes1.ts, 329, 16)) +>Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 332, 31)) +>bar : Symbol(Bar2.bar, Decl(conditionalTypes1.ts, 333, 16)) type FooBar = Foo2 | Bar2; ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) ->Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 324, 51)) ->Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 328, 31)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 333, 31)) +>Foo2 : Symbol(Foo2, Decl(conditionalTypes1.ts, 328, 51)) +>Bar2 : Symbol(Bar2, Decl(conditionalTypes1.ts, 332, 31)) declare interface ExtractFooBar { } ->ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 330, 26)) ->FB : Symbol(FB, Decl(conditionalTypes1.ts, 331, 32)) ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) +>ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 334, 26)) +>FB : Symbol(FB, Decl(conditionalTypes1.ts, 335, 32)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 333, 31)) type Extracted = { ->Extracted : Symbol(Extracted, Decl(conditionalTypes1.ts, 331, 54)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) +>Extracted : Symbol(Extracted, Decl(conditionalTypes1.ts, 335, 54)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 337, 15)) [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; ->K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) ->FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 329, 31)) ->ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 330, 26)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) ->Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 333, 15)) ->K : Symbol(K, Decl(conditionalTypes1.ts, 334, 5)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 337, 15)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 337, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5)) +>FooBar : Symbol(FooBar, Decl(conditionalTypes1.ts, 333, 31)) +>ExtractFooBar : Symbol(ExtractFooBar, Decl(conditionalTypes1.ts, 334, 26)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 337, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5)) +>Struct : Symbol(Struct, Decl(conditionalTypes1.ts, 337, 15)) +>K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5)) } diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 0d7624b07c8bf..538d8d75a0728 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -941,6 +941,21 @@ function f22(x: T extends (infer U)[] ? U[] : never) { >0 : 0 } +function f23(x: T extends (infer U)[] ? U[] : never) { +>f23 : (x: T extends infer U[] ? U[] : never) => void +>T : T +>x : T extends infer U[] ? U[] : never +>T : T +>U : U +>U : U + + let e = x[0]; // string +>e : string +>x[0] : string +>x : T extends infer U[] ? U[] : never +>0 : 0 +} + // Repros from #21664 type Eq = T extends U ? U extends T ? true : false : false; From 60a161e504e1280d85c856636eca954a6a0496a9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 29 Mar 2018 09:36:28 -0700 Subject: [PATCH 06/18] Fix formatting --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4228c6e7c7cd2..ee0bcbea014f4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8339,17 +8339,17 @@ namespace ts { // resolution of the conditional type such that a later instantiation will properly distribute // over union types. const isDeferred = root.isDistributive && maybeTypeOfKind(checkType, TypeFlags.Instantiable); - let combinedMapper: TypeMapper; - if (root.inferTypeParameters) { - const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None); + let combinedMapper: TypeMapper; + if (root.inferTypeParameters) { + const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None); if (!isDeferred) { // We don't want inferences from constraints as they may cause us to eagerly resolve the // conditional type instead of deferring resolution. Also, we always want strict function // types rules (i.e. proper contravariance) for inferences. inferTypes(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); } - combinedMapper = combineTypeMappers(mapper, context); - } + combinedMapper = combineTypeMappers(mapper, context); + } if (!isDeferred) { // Return union of trueType and falseType for 'any' since it matches anything if (checkType.flags & TypeFlags.Any) { From 052680d4ea3b0d6689d9fae1e59bd53099a9bbd5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 29 Mar 2018 10:16:31 -0700 Subject: [PATCH 07/18] Fix parent node walk termination condition in getConstrainedTypeVariable --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ee0bcbea014f4..13b8512c64fd4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7393,7 +7393,7 @@ namespace ts { function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) { let constraints: Type[]; - while (isPartOfTypeNode(node)) { + while (node && !isStatement(node)) { const parent = node.parent; if (parent.kind === SyntaxKind.ConditionalType && node === (parent).trueType) { const constraint = getImpliedConstraint(typeVariable, (parent).checkType, (parent).extendsType); From c4e21c912eb4bf16f41a2ef754a4ee528bbc10eb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 29 Mar 2018 10:22:11 -0700 Subject: [PATCH 08/18] Add regression test --- .../types/conditional/conditionalTypes1.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index 8aa524ba8183e..638cf473e19c6 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -341,3 +341,15 @@ declare interface ExtractFooBar { } type Extracted = { [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; } + +// Repro from #22985 + +type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? {[index: number]: RecursivePartial} : + T[P] extends object ? RecursivePartial : T[P]; +}; + +declare function assign(o: T, a: RecursivePartial): void; + +var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]} +assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) From b2e81bb55485610317e22d9be0d36c52a5b1aac0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 29 Mar 2018 10:22:20 -0700 Subject: [PATCH 09/18] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 12 ++++ .../baselines/reference/conditionalTypes1.js | 28 ++++++++ .../reference/conditionalTypes1.symbols | 54 +++++++++++++++ .../reference/conditionalTypes1.types | 68 +++++++++++++++++++ 4 files changed, 162 insertions(+) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index de06eeb832bf1..9599cc1bcbad5 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -501,4 +501,16 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS type Extracted = { [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; } + + // Repro from #22985 + + type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? {[index: number]: RecursivePartial} : + T[P] extends object ? RecursivePartial : T[P]; + }; + + declare function assign(o: T, a: RecursivePartial): void; + + var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]} + assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 1be708fed0125..a3f8d979b4081 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -339,6 +339,18 @@ declare interface ExtractFooBar { } type Extracted = { [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; } + +// Repro from #22985 + +type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? {[index: number]: RecursivePartial} : + T[P] extends object ? RecursivePartial : T[P]; +}; + +declare function assign(o: T, a: RecursivePartial): void; + +var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]} +assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) //// [conditionalTypes1.js] @@ -435,6 +447,8 @@ var f45 = function (value) { return value; }; // Error // Repro from #21863 function f50() { } +var a = { o: 1, b: 2, c: [{ a: 1, c: '213' }] }; +assign(a, { o: 2, c: { 0: { a: 2, c: '213123' } } }); //// [conditionalTypes1.d.ts] @@ -687,3 +701,17 @@ interface ExtractFooBar { declare type Extracted = { [K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar : Struct[K]; }; +declare type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? { + [index: number]: RecursivePartial; + } : T[P] extends object ? RecursivePartial : T[P]; +}; +declare function assign(o: T, a: RecursivePartial): void; +declare var a: { + o: number; + b: number; + c: { + a: number; + c: string; + }[]; +}; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index ae13ff75913c0..fb0ce83e0a7ce 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -1317,3 +1317,57 @@ type Extracted = { >K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5)) } +// Repro from #22985 + +type RecursivePartial = { +>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) + + [P in keyof T]?: T[P] extends Array ? {[index: number]: RecursivePartial} : +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>index : Symbol(index, Decl(conditionalTypes1.ts, 344, 47)) +>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) + + T[P] extends object ? RecursivePartial : T[P]; +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) +>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22)) +>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3)) + +}; + +declare function assign(o: T, a: RecursivePartial): void; +>assign : Symbol(assign, Decl(conditionalTypes1.ts, 346, 2)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24)) +>o : Symbol(o, Decl(conditionalTypes1.ts, 348, 27)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 348, 32)) +>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24)) + +var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]} +>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 3)) +>o : Symbol(o, Decl(conditionalTypes1.ts, 350, 9)) +>b : Symbol(b, Decl(conditionalTypes1.ts, 350, 14)) +>c : Symbol(c, Decl(conditionalTypes1.ts, 350, 20)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 26)) +>c : Symbol(c, Decl(conditionalTypes1.ts, 350, 31)) + +assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) +>assign : Symbol(assign, Decl(conditionalTypes1.ts, 346, 2)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 3)) +>o : Symbol(o, Decl(conditionalTypes1.ts, 351, 11)) +>c : Symbol(c, Decl(conditionalTypes1.ts, 351, 16)) +>0 : Symbol(0, Decl(conditionalTypes1.ts, 351, 21)) +>a : Symbol(a, Decl(conditionalTypes1.ts, 351, 25)) +>c : Symbol(c, Decl(conditionalTypes1.ts, 351, 30)) + diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 538d8d75a0728..2ba376781a5eb 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -1474,3 +1474,71 @@ type Extracted = { >K : K } +// Repro from #22985 + +type RecursivePartial = { +>RecursivePartial : RecursivePartial +>T : T + + [P in keyof T]?: T[P] extends Array ? {[index: number]: RecursivePartial} : +>P : P +>T : T +>T : T +>P : P +>Array : T[] +>index : number +>RecursivePartial : RecursivePartial +>T : T +>P : P + + T[P] extends object ? RecursivePartial : T[P]; +>T : T +>P : P +>RecursivePartial : RecursivePartial +>T : T +>P : P +>T : T +>P : P + +}; + +declare function assign(o: T, a: RecursivePartial): void; +>assign : (o: T, a: RecursivePartial) => void +>T : T +>o : T +>T : T +>a : RecursivePartial +>RecursivePartial : RecursivePartial +>T : T + +var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]} +>a : { o: number; b: number; c: { a: number; c: string; }[]; } +>{o: 1, b: 2, c: [{a: 1, c: '213'}]} : { o: number; b: number; c: { a: number; c: string; }[]; } +>o : number +>1 : 1 +>b : number +>2 : 2 +>c : { a: number; c: string; }[] +>[{a: 1, c: '213'}] : { a: number; c: string; }[] +>{a: 1, c: '213'} : { a: number; c: string; } +>a : number +>1 : 1 +>c : string +>'213' : "213" + +assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) +>assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) : void +>assign : (o: T, a: RecursivePartial) => void +>a : { o: number; b: number; c: { a: number; c: string; }[]; } +>{o: 2, c: {0: {a: 2, c: '213123'}}} : { o: number; c: { 0: { a: number; c: string; }; }; } +>o : number +>2 : 2 +>c : { 0: { a: number; c: string; }; } +>{0: {a: 2, c: '213123'}} : { 0: { a: number; c: string; }; } +>0 : { a: number; c: string; } +>{a: 2, c: '213123'} : { a: number; c: string; } +>a : number +>2 : 2 +>c : string +>'213123' : "213123" + From c0986d40bf17cc055640344455aaeb5a6197e26f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 30 Mar 2018 15:28:01 -0700 Subject: [PATCH 10/18] Constraint of 'T extends U ? T : F' should be 'T & U | F' --- src/compiler/checker.ts | 32 +++++++++++++++++++++++--------- src/compiler/types.ts | 2 +- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 13b8512c64fd4..7cf3932f46f6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6208,7 +6208,12 @@ namespace ts { } function getDefaultConstraintOfConditionalType(type: ConditionalType) { - return getUnionType([getInferredTrueTypeFromConditionalType(type), getFalseTypeFromConditionalType(type)]); + if (!type.resolvedDefaultConstraint) { + const rootTrueType = type.root.trueType; + const rootTrueConstraint = rootTrueType.flags & TypeFlags.Substitution ? (rootTrueType).substitute : rootTrueType; + type.resolvedDefaultConstraint = getUnionType([instantiateType(rootTrueConstraint, type.combinedMapper || type.mapper), getFalseTypeFromConditionalType(type)]); + } + return type.resolvedDefaultConstraint; } function getConstraintOfDistributiveConditionalType(type: ConditionalType): Type { @@ -6221,7 +6226,10 @@ namespace ts { const constraint = getConstraintOfType(type.checkType); if (constraint) { const mapper = createTypeMapper([type.root.checkType], [constraint]); - return getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper)); + const instantiated = getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper)); + if (!(instantiated.flags & TypeFlags.Never)) { + return instantiated; + } } } return undefined; @@ -8393,12 +8401,6 @@ namespace ts { return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper)); } - function getInferredTrueTypeFromConditionalType(type: ConditionalType) { - return type.combinedMapper ? - type.resolvedInferredTrueType || (type.resolvedInferredTrueType = instantiateType(type.root.trueType, type.combinedMapper)) : - getTrueTypeFromConditionalType(type); - } - function getInferTypeParameters(node: ConditionalTypeNode): TypeParameter[] { let result: TypeParameter[]; if (node.locals) { @@ -8411,13 +8413,25 @@ namespace ts { return result; } + function getTopConditionalType(node: Node): ConditionalTypeNode { + let result: ConditionalTypeNode; + while (node) { + if (node.kind === SyntaxKind.ConditionalType) { + result = node; + } + node = node.parent; + } + return result; + } + function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { const checkType = getTypeFromTypeNode(node.checkType); const aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node); const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true); - const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, node)); + const topNode = getTopConditionalType(node); + const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, topNode)); const root: ConditionalRoot = { node, checkType, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d07166d1381f7..719f9397b9602 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3848,7 +3848,7 @@ namespace ts { resolvedTrueType?: Type; resolvedFalseType?: Type; /* @internal */ - resolvedInferredTrueType?: Type; + resolvedDefaultConstraint?: Type; /* @internal */ mapper?: TypeMapper; /* @internal */ From e0399855f48cfe763d1c260550be215407a88f47 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 30 Mar 2018 16:21:16 -0700 Subject: [PATCH 11/18] Add tests --- .../types/conditional/conditionalTypes2.ts | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts index 5ba189236b05b..c3418cf924dee 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes2.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -28,6 +28,56 @@ function f3(a: Invariant, b: Invariant) { b = a; // Error } +// Extract is a T that is known to be a Function +function isFunction(value: T): value is Extract { + return typeof value === "function"; +} + +function getFunction(item: T) { + if (isFunction(item)) { + return item; + } + throw new Error(); +} + +function f10(x: T) { + if (isFunction(x)) { + const f: Function = x; + const t: T = x; + } +} + +function f11(x: string | (() => string) | undefined) { + if (isFunction(x)) { + x(); + } +} + +function f12(x: string | (() => string) | undefined) { + const f = getFunction(x); // () => string + f(); +} + +type Foo = { foo: string }; +type Bar = { bar: string }; + +declare function fooBar(x: { foo: string, bar: string }): void; +declare function fooBat(x: { foo: string, bat: string }): void; + +type Extract2 = T extends U ? T extends V ? T : never : never; + +function f20(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBar(x); + fooBar(y); + fooBar(z); +} + +function f21(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBat(x); // Error + fooBat(y); // Error + fooBat(z); // Error +} + // Repros from #22860 class Opt { @@ -59,3 +109,15 @@ interface B1 extends A1 { bat: B1>; boom: T extends any ? true : true } + +// Repro from #22899 + +declare function toString1(value: object | Function): string ; +declare function toString2(value: Function): string ; + +function foo(value: T) { + if (isFunction(value)) { + toString1(value); + toString2(value); + } +} From 32ad68a9297222bb6ce497b1e6e1b92cf8a46314 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 30 Mar 2018 16:21:23 -0700 Subject: [PATCH 12/18] Accept new baselines --- .../reference/conditionalTypes2.errors.txt | 91 ++++- .../baselines/reference/conditionalTypes2.js | 128 +++++++ .../reference/conditionalTypes2.symbols | 339 ++++++++++++++---- .../reference/conditionalTypes2.types | 228 ++++++++++++ 4 files changed, 720 insertions(+), 66 deletions(-) diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index a41522102682f..7e12ca8523b5e 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -10,9 +10,21 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS23 Types of property 'foo' are incompatible. Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'. Type 'A' is not assignable to type 'B'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(73,12): error TS2345: Argument of type 'Extract, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'. + Type 'Bar & Extract' is not assignable to type '{ foo: string; bat: string; }'. + Property 'bat' is missing in type 'Bar & Foo'. + Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. + Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'. + Property 'bat' is missing in type 'Bar & Foo'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(74,12): error TS2345: Argument of type 'Extract' is not assignable to parameter of type '{ foo: string; bat: string; }'. + Type 'Foo & Bar & T' is not assignable to type '{ foo: string; bat: string; }'. + Property 'bat' is missing in type 'Foo & Bar'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2' is not assignable to parameter of type '{ foo: string; bat: string; }'. + Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'. + Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'. -==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (4 errors) ==== +==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (7 errors) ==== interface Covariant { foo: T extends string ? T : number; } @@ -56,6 +68,71 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS23 !!! error TS2322: Type 'A' is not assignable to type 'B'. } + // Extract is a T that is known to be a Function + function isFunction(value: T): value is Extract { + return typeof value === "function"; + } + + function getFunction(item: T) { + if (isFunction(item)) { + return item; + } + throw new Error(); + } + + function f10(x: T) { + if (isFunction(x)) { + const f: Function = x; + const t: T = x; + } + } + + function f11(x: string | (() => string) | undefined) { + if (isFunction(x)) { + x(); + } + } + + function f12(x: string | (() => string) | undefined) { + const f = getFunction(x); // () => string + f(); + } + + type Foo = { foo: string }; + type Bar = { bar: string }; + + declare function fooBar(x: { foo: string, bar: string }): void; + declare function fooBat(x: { foo: string, bat: string }): void; + + type Extract2 = T extends U ? T extends V ? T : never : never; + + function f20(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBar(x); + fooBar(y); + fooBar(z); + } + + function f21(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBat(x); // Error + ~ +!!! error TS2345: Argument of type 'Extract, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'. +!!! error TS2345: Type 'Bar & Extract' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo'. +!!! error TS2345: Type 'Extract' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo'. + fooBat(y); // Error + ~ +!!! error TS2345: Argument of type 'Extract' is not assignable to parameter of type '{ foo: string; bat: string; }'. +!!! error TS2345: Type 'Foo & Bar & T' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Property 'bat' is missing in type 'Foo & Bar'. + fooBat(z); // Error + ~ +!!! error TS2345: Argument of type 'Extract2' is not assignable to parameter of type '{ foo: string; bat: string; }'. +!!! error TS2345: Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'. +!!! error TS2345: Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'. + } + // Repros from #22860 class Opt { @@ -87,4 +164,16 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS23 bat: B1>; boom: T extends any ? true : true } + + // Repro from #22899 + + declare function toString1(value: object | Function): string ; + declare function toString2(value: Function): string ; + + function foo(value: T) { + if (isFunction(value)) { + toString1(value); + toString2(value); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes2.js b/tests/baselines/reference/conditionalTypes2.js index 5193bae3345d3..ee2c1fe27fbad 100644 --- a/tests/baselines/reference/conditionalTypes2.js +++ b/tests/baselines/reference/conditionalTypes2.js @@ -26,6 +26,56 @@ function f3(a: Invariant, b: Invariant) { b = a; // Error } +// Extract is a T that is known to be a Function +function isFunction(value: T): value is Extract { + return typeof value === "function"; +} + +function getFunction(item: T) { + if (isFunction(item)) { + return item; + } + throw new Error(); +} + +function f10(x: T) { + if (isFunction(x)) { + const f: Function = x; + const t: T = x; + } +} + +function f11(x: string | (() => string) | undefined) { + if (isFunction(x)) { + x(); + } +} + +function f12(x: string | (() => string) | undefined) { + const f = getFunction(x); // () => string + f(); +} + +type Foo = { foo: string }; +type Bar = { bar: string }; + +declare function fooBar(x: { foo: string, bar: string }): void; +declare function fooBat(x: { foo: string, bat: string }): void; + +type Extract2 = T extends U ? T extends V ? T : never : never; + +function f20(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBar(x); + fooBar(y); + fooBar(z); +} + +function f21(x: Extract, Bar>, y: Extract, z: Extract2) { + fooBat(x); // Error + fooBat(y); // Error + fooBat(z); // Error +} + // Repros from #22860 class Opt { @@ -57,6 +107,18 @@ interface B1 extends A1 { bat: B1>; boom: T extends any ? true : true } + +// Repro from #22899 + +declare function toString1(value: object | Function): string ; +declare function toString2(value: Function): string ; + +function foo(value: T) { + if (isFunction(value)) { + toString1(value); + toString2(value); + } +} //// [conditionalTypes2.js] @@ -73,6 +135,41 @@ function f3(a, b) { a = b; // Error b = a; // Error } +// Extract is a T that is known to be a Function +function isFunction(value) { + return typeof value === "function"; +} +function getFunction(item) { + if (isFunction(item)) { + return item; + } + throw new Error(); +} +function f10(x) { + if (isFunction(x)) { + var f = x; + var t = x; + } +} +function f11(x) { + if (isFunction(x)) { + x(); + } +} +function f12(x) { + var f = getFunction(x); // () => string + f(); +} +function f20(x, y, z) { + fooBar(x); + fooBar(y); + fooBar(z); +} +function f21(x, y, z) { + fooBat(x); // Error + fooBat(y); // Error + fooBat(z); // Error +} // Repros from #22860 var Opt = /** @class */ (function () { function Opt() { @@ -93,6 +190,12 @@ var Vector = /** @class */ (function () { }; return Vector; }()); +function foo(value) { + if (isFunction(value)) { + toString1(value); + toString2(value); + } +} //// [conditionalTypes2.d.ts] @@ -108,6 +211,28 @@ interface Invariant { declare function f1(a: Covariant, b: Covariant): void; declare function f2(a: Contravariant, b: Contravariant): void; declare function f3(a: Invariant, b: Invariant): void; +declare function isFunction(value: T): value is Extract; +declare function getFunction(item: T): Extract; +declare function f10(x: T): void; +declare function f11(x: string | (() => string) | undefined): void; +declare function f12(x: string | (() => string) | undefined): void; +declare type Foo = { + foo: string; +}; +declare type Bar = { + bar: string; +}; +declare function fooBar(x: { + foo: string; + bar: string; +}): void; +declare function fooBat(x: { + foo: string; + bat: string; +}): void; +declare type Extract2 = T extends U ? T extends V ? T : never : never; +declare function f20(x: Extract, Bar>, y: Extract, z: Extract2): void; +declare function f21(x: Extract, Bar>, y: Extract, z: Extract2): void; declare class Opt { toVector(): Vector; } @@ -126,3 +251,6 @@ interface B1 extends A1 { bat: B1>; boom: T extends any ? true : true; } +declare function toString1(value: object | Function): string; +declare function toString2(value: Function): string; +declare function foo(value: T): void; diff --git a/tests/baselines/reference/conditionalTypes2.symbols b/tests/baselines/reference/conditionalTypes2.symbols index 4d9cd27238be5..ef58dc6229c2e 100644 --- a/tests/baselines/reference/conditionalTypes2.symbols +++ b/tests/baselines/reference/conditionalTypes2.symbols @@ -93,16 +93,193 @@ function f3(a: Invariant, b: Invariant) { >a : Symbol(a, Decl(conditionalTypes2.ts, 22, 28)) } +// Extract is a T that is known to be a Function +function isFunction(value: T): value is Extract { +>isFunction : Symbol(isFunction, Decl(conditionalTypes2.ts, 25, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 28, 20)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 28, 23)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 28, 20)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 28, 23)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 28, 20)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + return typeof value === "function"; +>value : Symbol(value, Decl(conditionalTypes2.ts, 28, 23)) +} + +function getFunction(item: T) { +>getFunction : Symbol(getFunction, Decl(conditionalTypes2.ts, 30, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 32, 21)) +>item : Symbol(item, Decl(conditionalTypes2.ts, 32, 24)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 32, 21)) + + if (isFunction(item)) { +>isFunction : Symbol(isFunction, Decl(conditionalTypes2.ts, 25, 1)) +>item : Symbol(item, Decl(conditionalTypes2.ts, 32, 24)) + + return item; +>item : Symbol(item, Decl(conditionalTypes2.ts, 32, 24)) + } + throw new Error(); +>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} + +function f10(x: T) { +>f10 : Symbol(f10, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 39, 16)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) + + if (isFunction(x)) { +>isFunction : Symbol(isFunction, Decl(conditionalTypes2.ts, 25, 1)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 39, 16)) + + const f: Function = x; +>f : Symbol(f, Decl(conditionalTypes2.ts, 41, 13)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 39, 16)) + + const t: T = x; +>t : Symbol(t, Decl(conditionalTypes2.ts, 42, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 39, 16)) + } +} + +function f11(x: string | (() => string) | undefined) { +>f11 : Symbol(f11, Decl(conditionalTypes2.ts, 44, 1)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 46, 13)) + + if (isFunction(x)) { +>isFunction : Symbol(isFunction, Decl(conditionalTypes2.ts, 25, 1)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 46, 13)) + + x(); +>x : Symbol(x, Decl(conditionalTypes2.ts, 46, 13)) + } +} + +function f12(x: string | (() => string) | undefined) { +>f12 : Symbol(f12, Decl(conditionalTypes2.ts, 50, 1)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 52, 13)) + + const f = getFunction(x); // () => string +>f : Symbol(f, Decl(conditionalTypes2.ts, 53, 9)) +>getFunction : Symbol(getFunction, Decl(conditionalTypes2.ts, 30, 1)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 52, 13)) + + f(); +>f : Symbol(f, Decl(conditionalTypes2.ts, 53, 9)) +} + +type Foo = { foo: string }; +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>foo : Symbol(foo, Decl(conditionalTypes2.ts, 57, 12)) + +type Bar = { bar: string }; +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) +>bar : Symbol(bar, Decl(conditionalTypes2.ts, 58, 12)) + +declare function fooBar(x: { foo: string, bar: string }): void; +>fooBar : Symbol(fooBar, Decl(conditionalTypes2.ts, 58, 27)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 60, 24)) +>foo : Symbol(foo, Decl(conditionalTypes2.ts, 60, 28)) +>bar : Symbol(bar, Decl(conditionalTypes2.ts, 60, 41)) + +declare function fooBat(x: { foo: string, bat: string }): void; +>fooBat : Symbol(fooBat, Decl(conditionalTypes2.ts, 60, 63)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 61, 24)) +>foo : Symbol(foo, Decl(conditionalTypes2.ts, 61, 28)) +>bat : Symbol(bat, Decl(conditionalTypes2.ts, 61, 41)) + +type Extract2 = T extends U ? T extends V ? T : never : never; +>Extract2 : Symbol(Extract2, Decl(conditionalTypes2.ts, 61, 63)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 63, 14)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 63, 16)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 63, 19)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 63, 14)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 63, 16)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 63, 14)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 63, 19)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 63, 14)) + +function f20(x: Extract, Bar>, y: Extract, z: Extract2) { +>f20 : Symbol(f20, Decl(conditionalTypes2.ts, 63, 71)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 65, 13)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 65, 16)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 65, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) +>y : Symbol(y, Decl(conditionalTypes2.ts, 65, 49)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 65, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) +>z : Symbol(z, Decl(conditionalTypes2.ts, 65, 75)) +>Extract2 : Symbol(Extract2, Decl(conditionalTypes2.ts, 61, 63)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 65, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) + + fooBar(x); +>fooBar : Symbol(fooBar, Decl(conditionalTypes2.ts, 58, 27)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 65, 16)) + + fooBar(y); +>fooBar : Symbol(fooBar, Decl(conditionalTypes2.ts, 58, 27)) +>y : Symbol(y, Decl(conditionalTypes2.ts, 65, 49)) + + fooBar(z); +>fooBar : Symbol(fooBar, Decl(conditionalTypes2.ts, 58, 27)) +>z : Symbol(z, Decl(conditionalTypes2.ts, 65, 75)) +} + +function f21(x: Extract, Bar>, y: Extract, z: Extract2) { +>f21 : Symbol(f21, Decl(conditionalTypes2.ts, 69, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 71, 13)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 71, 16)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 71, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) +>y : Symbol(y, Decl(conditionalTypes2.ts, 71, 49)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 71, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) +>z : Symbol(z, Decl(conditionalTypes2.ts, 71, 75)) +>Extract2 : Symbol(Extract2, Decl(conditionalTypes2.ts, 61, 63)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 71, 13)) +>Foo : Symbol(Foo, Decl(conditionalTypes2.ts, 55, 1)) +>Bar : Symbol(Bar, Decl(conditionalTypes2.ts, 57, 27)) + + fooBat(x); // Error +>fooBat : Symbol(fooBat, Decl(conditionalTypes2.ts, 60, 63)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 71, 16)) + + fooBat(y); // Error +>fooBat : Symbol(fooBat, Decl(conditionalTypes2.ts, 60, 63)) +>y : Symbol(y, Decl(conditionalTypes2.ts, 71, 49)) + + fooBat(z); // Error +>fooBat : Symbol(fooBat, Decl(conditionalTypes2.ts, 60, 63)) +>z : Symbol(z, Decl(conditionalTypes2.ts, 71, 75)) +} + // Repros from #22860 class Opt { ->Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 29, 10)) +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 75, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 79, 10)) toVector(): Vector { ->toVector : Symbol(Opt.toVector, Decl(conditionalTypes2.ts, 29, 14)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 29, 10)) +>toVector : Symbol(Opt.toVector, Decl(conditionalTypes2.ts, 79, 14)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 79, 10)) return undefined; >undefined : Symbol(undefined) @@ -110,67 +287,67 @@ class Opt { } interface Seq { ->Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 35, 14)) +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 83, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 85, 14)) tail(): Opt>; ->tail : Symbol(Seq.tail, Decl(conditionalTypes2.ts, 35, 18)) ->Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) ->Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 35, 14)) +>tail : Symbol(Seq.tail, Decl(conditionalTypes2.ts, 85, 18)) +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 75, 1)) +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 83, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 85, 14)) } class Vector implements Seq { ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 83, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) tail(): Opt> { ->tail : Symbol(Vector.tail, Decl(conditionalTypes2.ts, 39, 35)) ->Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>tail : Symbol(Vector.tail, Decl(conditionalTypes2.ts, 89, 35)) +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 75, 1)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) return undefined; >undefined : Symbol(undefined) } partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; ->partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 43, 28)) ->v : Symbol(v, Decl(conditionalTypes2.ts, 43, 39)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->v : Symbol(v, Decl(conditionalTypes2.ts, 43, 39)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 92, 5), Decl(conditionalTypes2.ts, 93, 88), Decl(conditionalTypes2.ts, 94, 64)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 93, 15)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 93, 28)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 93, 39)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 93, 39)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 93, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 93, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) >Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 93, 15)) partition2(predicate:(x:T)=>boolean): [Vector,Vector]; ->partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) ->predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 44, 15)) ->x : Symbol(x, Decl(conditionalTypes2.ts, 44, 26)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 92, 5), Decl(conditionalTypes2.ts, 93, 88), Decl(conditionalTypes2.ts, 94, 64)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 94, 15)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 94, 26)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) partition2(predicate:(v:T)=>boolean): [Vector,Vector] { ->partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 45, 15)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 45, 28)) ->v : Symbol(v, Decl(conditionalTypes2.ts, 45, 39)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) ->U : Symbol(U, Decl(conditionalTypes2.ts, 45, 15)) ->Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 92, 5), Decl(conditionalTypes2.ts, 93, 88), Decl(conditionalTypes2.ts, 94, 64)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 95, 15)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 95, 28)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 95, 39)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 89, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 95, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 87, 1)) return undefined; >undefined : Symbol(undefined) @@ -178,30 +355,62 @@ class Vector implements Seq { } interface A1 { ->A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 50, 13)) +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 98, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 100, 13)) bat: B1>; ->bat : Symbol(A1.bat, Decl(conditionalTypes2.ts, 50, 17)) ->B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) ->A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 50, 13)) +>bat : Symbol(A1.bat, Decl(conditionalTypes2.ts, 100, 17)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 102, 1)) +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 98, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 100, 13)) } interface B1 extends A1 { ->B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) ->A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 102, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 104, 13)) +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 98, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 104, 13)) bat: B1>; ->bat : Symbol(B1.bat, Decl(conditionalTypes2.ts, 54, 31)) ->B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) ->B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) +>bat : Symbol(B1.bat, Decl(conditionalTypes2.ts, 104, 31)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 102, 1)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 102, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 104, 13)) boom: T extends any ? true : true ->boom : Symbol(B1.boom, Decl(conditionalTypes2.ts, 55, 19)) ->T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) +>boom : Symbol(B1.boom, Decl(conditionalTypes2.ts, 105, 19)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 104, 13)) +} + +// Repro from #22899 + +declare function toString1(value: object | Function): string ; +>toString1 : Symbol(toString1, Decl(conditionalTypes2.ts, 107, 1)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 111, 27)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +declare function toString2(value: Function): string ; +>toString2 : Symbol(toString2, Decl(conditionalTypes2.ts, 111, 62)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 112, 27)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + +function foo(value: T) { +>foo : Symbol(foo, Decl(conditionalTypes2.ts, 112, 53)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 114, 13)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 114, 16)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 114, 13)) + + if (isFunction(value)) { +>isFunction : Symbol(isFunction, Decl(conditionalTypes2.ts, 25, 1)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 114, 16)) + + toString1(value); +>toString1 : Symbol(toString1, Decl(conditionalTypes2.ts, 107, 1)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 114, 16)) + + toString2(value); +>toString2 : Symbol(toString2, Decl(conditionalTypes2.ts, 111, 62)) +>value : Symbol(value, Decl(conditionalTypes2.ts, 114, 16)) + } } diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index e3dad1fc280e5..249c05f1ad394 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -99,6 +99,199 @@ function f3(a: Invariant, b: Invariant) { >a : Invariant } +// Extract is a T that is known to be a Function +function isFunction(value: T): value is Extract { +>isFunction : (value: T) => value is Extract +>T : T +>value : T +>T : T +>value : any +>Extract : Extract +>T : T +>Function : Function + + return typeof value === "function"; +>typeof value === "function" : boolean +>typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>value : T +>"function" : "function" +} + +function getFunction(item: T) { +>getFunction : (item: T) => Extract +>T : T +>item : T +>T : T + + if (isFunction(item)) { +>isFunction(item) : boolean +>isFunction : (value: T) => value is Extract +>item : T + + return item; +>item : Extract + } + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor +} + +function f10(x: T) { +>f10 : (x: T) => void +>T : T +>x : T +>T : T + + if (isFunction(x)) { +>isFunction(x) : boolean +>isFunction : (value: T) => value is Extract +>x : T + + const f: Function = x; +>f : Function +>Function : Function +>x : Extract + + const t: T = x; +>t : T +>T : T +>x : Extract + } +} + +function f11(x: string | (() => string) | undefined) { +>f11 : (x: string | (() => string) | undefined) => void +>x : string | (() => string) | undefined + + if (isFunction(x)) { +>isFunction(x) : boolean +>isFunction : (value: T) => value is Extract +>x : string | (() => string) | undefined + + x(); +>x() : string +>x : () => string + } +} + +function f12(x: string | (() => string) | undefined) { +>f12 : (x: string | (() => string) | undefined) => void +>x : string | (() => string) | undefined + + const f = getFunction(x); // () => string +>f : () => string +>getFunction(x) : () => string +>getFunction : (item: T) => Extract +>x : string | (() => string) | undefined + + f(); +>f() : string +>f : () => string +} + +type Foo = { foo: string }; +>Foo : Foo +>foo : string + +type Bar = { bar: string }; +>Bar : Bar +>bar : string + +declare function fooBar(x: { foo: string, bar: string }): void; +>fooBar : (x: { foo: string; bar: string; }) => void +>x : { foo: string; bar: string; } +>foo : string +>bar : string + +declare function fooBat(x: { foo: string, bat: string }): void; +>fooBat : (x: { foo: string; bat: string; }) => void +>x : { foo: string; bat: string; } +>foo : string +>bat : string + +type Extract2 = T extends U ? T extends V ? T : never : never; +>Extract2 : Extract2 +>T : T +>U : U +>V : V +>T : T +>U : U +>T : T +>V : V +>T : T + +function f20(x: Extract, Bar>, y: Extract, z: Extract2) { +>f20 : (x: Extract, Bar>, y: Extract, z: Extract2) => void +>T : T +>x : Extract, Bar> +>Extract : Extract +>Extract : Extract +>T : T +>Foo : Foo +>Bar : Bar +>y : Extract +>Extract : Extract +>T : T +>Foo : Foo +>Bar : Bar +>z : Extract2 +>Extract2 : Extract2 +>T : T +>Foo : Foo +>Bar : Bar + + fooBar(x); +>fooBar(x) : void +>fooBar : (x: { foo: string; bar: string; }) => void +>x : Extract, Bar> + + fooBar(y); +>fooBar(y) : void +>fooBar : (x: { foo: string; bar: string; }) => void +>y : Extract + + fooBar(z); +>fooBar(z) : void +>fooBar : (x: { foo: string; bar: string; }) => void +>z : Extract2 +} + +function f21(x: Extract, Bar>, y: Extract, z: Extract2) { +>f21 : (x: Extract, Bar>, y: Extract, z: Extract2) => void +>T : T +>x : Extract, Bar> +>Extract : Extract +>Extract : Extract +>T : T +>Foo : Foo +>Bar : Bar +>y : Extract +>Extract : Extract +>T : T +>Foo : Foo +>Bar : Bar +>z : Extract2 +>Extract2 : Extract2 +>T : T +>Foo : Foo +>Bar : Bar + + fooBat(x); // Error +>fooBat(x) : void +>fooBat : (x: { foo: string; bat: string; }) => void +>x : Extract, Bar> + + fooBat(y); // Error +>fooBat(y) : void +>fooBat : (x: { foo: string; bat: string; }) => void +>y : Extract + + fooBat(z); // Error +>fooBat(z) : void +>fooBat : (x: { foo: string; bat: string; }) => void +>z : Extract2 +} + // Repros from #22860 class Opt { @@ -216,3 +409,38 @@ interface B1 extends A1 { >true : true } +// Repro from #22899 + +declare function toString1(value: object | Function): string ; +>toString1 : (value: object | Function) => string +>value : object | Function +>Function : Function + +declare function toString2(value: Function): string ; +>toString2 : (value: Function) => string +>value : Function +>Function : Function + +function foo(value: T) { +>foo : (value: T) => void +>T : T +>value : T +>T : T + + if (isFunction(value)) { +>isFunction(value) : boolean +>isFunction : (value: T) => value is Extract +>value : T + + toString1(value); +>toString1(value) : string +>toString1 : (value: object | Function) => string +>value : Extract + + toString2(value); +>toString2(value) : string +>toString2 : (value: Function) => string +>value : Extract + } +} + From 840c64a6050ede7b915c25ba269d850a62d837b6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Apr 2018 09:22:46 -0700 Subject: [PATCH 13/18] Less aggressive test for type parameter references in conditional types --- src/compiler/checker.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7cf3932f46f6e..4e8f5fbf966df 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8413,15 +8413,19 @@ namespace ts { return result; } - function getTopConditionalType(node: Node): ConditionalTypeNode { - let result: ConditionalTypeNode; + function isPossiblyReferencedInConditionalType(tp: TypeParameter, node: Node) { + if (isTypeParameterPossiblyReferenced(tp, node)) { + return true; + } while (node) { if (node.kind === SyntaxKind.ConditionalType) { - result = node; + if (isTypeParameterPossiblyReferenced(tp, (node).extendsType)) { + return true; + } } node = node.parent; } - return result; + return false; } function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type { @@ -8430,8 +8434,7 @@ namespace ts { const checkType = getTypeFromTypeNode(node.checkType); const aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node); const allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true); - const topNode = getTopConditionalType(node); - const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, topNode)); + const outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : filter(allOuterTypeParameters, tp => isPossiblyReferencedInConditionalType(tp, node)); const root: ConditionalRoot = { node, checkType, From 05e10eee30ba0b658cb37ab3a13ad760c06e645b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Apr 2018 09:23:00 -0700 Subject: [PATCH 14/18] Add regression test --- .../types/conditional/conditionalTypes2.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts index c3418cf924dee..4002ab6a0a754 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes2.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -121,3 +121,18 @@ function foo(value: T) { toString2(value); } } + +// Repro from #23052 + +type A = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } + : T extends V ? T : never; + +type B = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } + : T extends V ? T : never; + +type C = + { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; From 2be103a20045547e7a658d6a5207542392501d79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Apr 2018 09:23:16 -0700 Subject: [PATCH 15/18] Accept new baselines --- .../reference/conditionalTypes2.errors.txt | 15 ++++ .../baselines/reference/conditionalTypes2.js | 30 +++++++ .../reference/conditionalTypes2.symbols | 82 +++++++++++++++++++ .../reference/conditionalTypes2.types | 82 +++++++++++++++++++ 4 files changed, 209 insertions(+) diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index 7e12ca8523b5e..0e7844babc616 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -176,4 +176,19 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 toString2(value); } } + + // Repro from #23052 + + type A = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } + : T extends V ? T : never; + + type B = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } + : T extends V ? T : never; + + type C = + { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes2.js b/tests/baselines/reference/conditionalTypes2.js index ee2c1fe27fbad..7afb39d42bb7d 100644 --- a/tests/baselines/reference/conditionalTypes2.js +++ b/tests/baselines/reference/conditionalTypes2.js @@ -119,6 +119,21 @@ function foo(value: T) { toString2(value); } } + +// Repro from #23052 + +type A = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } + : T extends V ? T : never; + +type B = + T extends object + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } + : T extends V ? T : never; + +type C = + { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; //// [conditionalTypes2.js] @@ -254,3 +269,18 @@ interface B1 extends A1 { declare function toString1(value: object | Function): string; declare function toString2(value: Function): string; declare function foo(value: T): void; +declare type A = T extends object ? { + [Q in { + [P in keyof T]: T[P] extends V ? P : P; + }[keyof T]]: A; +} : T extends V ? T : never; +declare type B = T extends object ? { + [Q in { + [P in keyof T]: T[P] extends V ? P : P; + }[keyof T]]: B; +} : T extends V ? T : never; +declare type C = { + [Q in { + [P in keyof T]: T[P] extends V ? P : P; + }[keyof T]]: C; +}; diff --git a/tests/baselines/reference/conditionalTypes2.symbols b/tests/baselines/reference/conditionalTypes2.symbols index ef58dc6229c2e..00509458253ff 100644 --- a/tests/baselines/reference/conditionalTypes2.symbols +++ b/tests/baselines/reference/conditionalTypes2.symbols @@ -414,3 +414,85 @@ function foo(value: T) { } } +// Repro from #23052 + +type A = +>A : Symbol(A, Decl(conditionalTypes2.ts, 119, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 123, 12)) + + T extends object +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) + + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 125, 9)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 125, 17)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 119, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 125, 9)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 123, 12)) + + : T extends V ? T : never; +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 123, 9)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 123, 7)) + +type B = +>B : Symbol(B, Decl(conditionalTypes2.ts, 126, 30)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9)) + + T extends object +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) + + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 130, 9)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 130, 17)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 126, 30)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 130, 9)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9)) + + : T extends V ? T : never; +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 128, 9)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 128, 7)) + +type C = +>C : Symbol(C, Decl(conditionalTypes2.ts, 131, 30)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12)) + + { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 134, 5)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13)) +>P : Symbol(P, Decl(conditionalTypes2.ts, 134, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7)) +>C : Symbol(C, Decl(conditionalTypes2.ts, 131, 30)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 133, 7)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 134, 5)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12)) + diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index 249c05f1ad394..5af4de235c8a3 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -444,3 +444,85 @@ function foo(value: T) { } } +// Repro from #23052 + +type A = +>A : A +>T : T +>V : V +>E : E + + T extends object +>T : T + + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } +>Q : Q +>P : P +>T : T +>T : T +>P : P +>V : V +>P : P +>P : P +>T : T +>A : A +>T : T +>Q : Q +>V : V +>E : E + + : T extends V ? T : never; +>T : T +>V : V +>T : T + +type B = +>B : B +>T : T +>V : V + + T extends object +>T : T + + ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } +>Q : Q +>P : P +>T : T +>T : T +>P : P +>V : V +>P : P +>P : P +>T : T +>B : B +>T : T +>Q : Q +>V : V + + : T extends V ? T : never; +>T : T +>V : V +>T : T + +type C = +>C : C +>T : T +>V : V +>E : E + + { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; +>Q : Q +>P : P +>T : T +>T : T +>P : P +>V : V +>P : P +>P : P +>T : T +>C : C +>T : T +>Q : Q +>V : V +>E : E + From 66adcc3f7a51dc5e7fee8805a7a3788db9969276 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Apr 2018 09:04:24 -0700 Subject: [PATCH 16/18] Only look up identifiers that could actually be type parameters --- src/compiler/checker.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4e8f5fbf966df..3a40b72d3b0e6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8978,6 +8978,11 @@ namespace ts { return type; } + function maybeTypeParameterReference(node: Node) { + return !(node.kind === SyntaxKind.QualifiedName || + node.parent.kind === SyntaxKind.TypeReference && (node.parent).typeArguments && node === (node.parent).typeName); + } + function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks // between the node and the type parameter declaration, if the node contains actual references to the @@ -8994,7 +8999,8 @@ namespace ts { case SyntaxKind.ThisType: return tp.isThisType; case SyntaxKind.Identifier: - return !tp.isThisType && isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp; + return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node) && + getTypeFromTypeNode(node) === tp; case SyntaxKind.TypeQuery: return true; } From d7c70fc6b7ae57f93912956872df7fe4770352d8 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Apr 2018 09:04:36 -0700 Subject: [PATCH 17/18] Add regression test --- .../types/conditional/conditionalTypes2.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts index 4002ab6a0a754..be75894546944 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes2.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -136,3 +136,14 @@ type B = type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + +// Repro from #23100 + +type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + +type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + +type C2 = + T extends object ? { [Q in keyof T]: C2; } : T; From f077460a06d65409e93896fc1da471835bc17c7b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 3 Apr 2018 09:04:42 -0700 Subject: [PATCH 18/18] Accept new baselines --- .../reference/conditionalTypes2.errors.txt | 11 ++++ .../baselines/reference/conditionalTypes2.js | 20 +++++++ .../reference/conditionalTypes2.symbols | 55 +++++++++++++++++++ .../reference/conditionalTypes2.types | 55 +++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index 0e7844babc616..c0c4211174cbe 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -191,4 +191,15 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + + // Repro from #23100 + + type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + + type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + + type C2 = + T extends object ? { [Q in keyof T]: C2; } : T; \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes2.js b/tests/baselines/reference/conditionalTypes2.js index 7afb39d42bb7d..1f95e7eb8d9f2 100644 --- a/tests/baselines/reference/conditionalTypes2.js +++ b/tests/baselines/reference/conditionalTypes2.js @@ -134,6 +134,17 @@ type B = type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; + +// Repro from #23100 + +type A2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; + +type B2 = + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; + +type C2 = + T extends object ? { [Q in keyof T]: C2; } : T; //// [conditionalTypes2.js] @@ -284,3 +295,12 @@ declare type C = { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; +declare type A2 = T extends object ? T extends any[] ? T : { + [Q in keyof T]: A2; +} : T; +declare type B2 = T extends object ? T extends any[] ? T : { + [Q in keyof T]: B2; +} : T; +declare type C2 = T extends object ? { + [Q in keyof T]: C2; +} : T; diff --git a/tests/baselines/reference/conditionalTypes2.symbols b/tests/baselines/reference/conditionalTypes2.symbols index 00509458253ff..fb03b868a1d39 100644 --- a/tests/baselines/reference/conditionalTypes2.symbols +++ b/tests/baselines/reference/conditionalTypes2.symbols @@ -496,3 +496,58 @@ type C = >V : Symbol(V, Decl(conditionalTypes2.ts, 133, 9)) >E : Symbol(E, Decl(conditionalTypes2.ts, 133, 12)) +// Repro from #23100 + +type A2 = +>A2 : Symbol(A2, Decl(conditionalTypes2.ts, 134, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 138, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 138, 13)) + + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 139, 48)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>A2 : Symbol(A2, Decl(conditionalTypes2.ts, 134, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 139, 48)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 138, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 138, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 138, 8)) + +type B2 = +>B2 : Symbol(B2, Decl(conditionalTypes2.ts, 139, 85)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 141, 10)) + + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 142, 48)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>B2 : Symbol(B2, Decl(conditionalTypes2.ts, 139, 85)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 142, 48)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 141, 10)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 141, 8)) + +type C2 = +>C2 : Symbol(C2, Decl(conditionalTypes2.ts, 142, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 144, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 144, 13)) + + T extends object ? { [Q in keyof T]: C2; } : T; +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 145, 26)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>C2 : Symbol(C2, Decl(conditionalTypes2.ts, 142, 82)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) +>Q : Symbol(Q, Decl(conditionalTypes2.ts, 145, 26)) +>V : Symbol(V, Decl(conditionalTypes2.ts, 144, 10)) +>E : Symbol(E, Decl(conditionalTypes2.ts, 144, 13)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 144, 8)) + diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types index 5af4de235c8a3..906bc7e27df28 100644 --- a/tests/baselines/reference/conditionalTypes2.types +++ b/tests/baselines/reference/conditionalTypes2.types @@ -526,3 +526,58 @@ type C = >V : V >E : E +// Repro from #23100 + +type A2 = +>A2 : A2 +>T : T +>V : V +>E : E + + T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; +>T : T +>T : T +>T : T +>Q : Q +>T : T +>A2 : A2 +>T : T +>Q : Q +>V : V +>E : E +>T : T + +type B2 = +>B2 : B2 +>T : T +>V : V + + T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; +>T : T +>T : T +>T : T +>Q : Q +>T : T +>B2 : B2 +>T : T +>Q : Q +>V : V +>T : T + +type C2 = +>C2 : C2 +>T : T +>V : V +>E : E + + T extends object ? { [Q in keyof T]: C2; } : T; +>T : T +>Q : Q +>T : T +>C2 : C2 +>T : T +>Q : Q +>V : V +>E : E +>T : T +