From 8ff8008fc0f9bf079329f87f34ea980f0a61b415 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 9 Aug 2018 16:31:54 -0400 Subject: [PATCH 1/3] Make T[K] yield never when T is never --- src/compiler/checker.ts | 2 +- .../nonPrimitiveConstraintOfIndexAccessType.errors.txt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b01649132ea0..fbd3fdd44b2bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9140,7 +9140,7 @@ namespace ts { } } if (!(indexType.flags & TypeFlags.Nullable) && isTypeAssignableToKind(indexType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike)) { - if (isTypeAny(objectType)) { + if (objectType.flags & (TypeFlags.Any | TypeFlags.Never)) { return objectType; } const indexInfo = isTypeAssignableToKind(indexType, TypeFlags.NumberLike) && getIndexInfoOfType(objectType, IndexKind.Number) || diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt index 56781157131a4..5784d8c46d0b4 100644 --- a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt @@ -3,6 +3,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessTy tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(9,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(12,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(15,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(18,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(21,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(24,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. @@ -37,6 +38,7 @@ tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessTy tp = s; ~~ !!! error TS2322: Type 'string' is not assignable to type 'T[P]'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. } function k(s: string, tp: T[P]): void { tp = s; From 89a8b5094ac9be0e412902d414779916ee3b45dd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 9 Aug 2018 16:33:54 -0400 Subject: [PATCH 2/3] Add test --- tests/cases/compiler/indexingTypesWithNever.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/cases/compiler/indexingTypesWithNever.ts b/tests/cases/compiler/indexingTypesWithNever.ts index 9044ded2ff4c3..b81bf533ebc70 100644 --- a/tests/cases/compiler/indexingTypesWithNever.ts +++ b/tests/cases/compiler/indexingTypesWithNever.ts @@ -109,3 +109,11 @@ declare const o3Test: ExpectType<{ a?: string; b?: number }, O3Props>; declare const o2Test: ExpectType<{ a?: string }, O2Props>; declare const o1Test: ExpectType<{}, O1Props>; declare const o0Test: ExpectType<{}, O0Props>; + +// Repro from #23005 + +type Example> = T['a']; + +type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" +type Res2 = Example<{ a: "x" }>; // "x" +type Res3 = Example; // never From df2af29977daaa6956b3c820749589e1a219ebbb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 9 Aug 2018 16:34:01 -0400 Subject: [PATCH 3/3] Accept new baselines --- .../reference/indexingTypesWithNever.js | 8 +++++++ .../reference/indexingTypesWithNever.symbols | 23 +++++++++++++++++++ .../reference/indexingTypesWithNever.types | 17 ++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/tests/baselines/reference/indexingTypesWithNever.js b/tests/baselines/reference/indexingTypesWithNever.js index 4e174fc4c9d91..33f0bcc8c3516 100644 --- a/tests/baselines/reference/indexingTypesWithNever.js +++ b/tests/baselines/reference/indexingTypesWithNever.js @@ -108,6 +108,14 @@ declare const o3Test: ExpectType<{ a?: string; b?: number }, O3Props>; declare const o2Test: ExpectType<{ a?: string }, O2Props>; declare const o1Test: ExpectType<{}, O1Props>; declare const o0Test: ExpectType<{}, O0Props>; + +// Repro from #23005 + +type Example> = T['a']; + +type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" +type Res2 = Example<{ a: "x" }>; // "x" +type Res3 = Example; // never //// [indexingTypesWithNever.js] diff --git a/tests/baselines/reference/indexingTypesWithNever.symbols b/tests/baselines/reference/indexingTypesWithNever.symbols index 1833e8c6377dc..9b93d00e50fcf 100644 --- a/tests/baselines/reference/indexingTypesWithNever.symbols +++ b/tests/baselines/reference/indexingTypesWithNever.symbols @@ -387,3 +387,26 @@ declare const o0Test: ExpectType<{}, O0Props>; >ExpectType : Symbol(ExpectType, Decl(indexingTypesWithNever.ts, 54, 22)) >O0Props : Symbol(O0Props, Decl(indexingTypesWithNever.ts, 102, 33)) +// Repro from #23005 + +type Example> = T['a']; +>Example : Symbol(Example, Decl(indexingTypesWithNever.ts, 108, 46)) +>T : Symbol(T, Decl(indexingTypesWithNever.ts, 112, 13)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(indexingTypesWithNever.ts, 112, 13)) + +type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" +>Res1 : Symbol(Res1, Decl(indexingTypesWithNever.ts, 112, 53)) +>Example : Symbol(Example, Decl(indexingTypesWithNever.ts, 108, 46)) +>a : Symbol(a, Decl(indexingTypesWithNever.ts, 114, 21)) +>a : Symbol(a, Decl(indexingTypesWithNever.ts, 114, 34)) + +type Res2 = Example<{ a: "x" }>; // "x" +>Res2 : Symbol(Res2, Decl(indexingTypesWithNever.ts, 114, 45)) +>Example : Symbol(Example, Decl(indexingTypesWithNever.ts, 108, 46)) +>a : Symbol(a, Decl(indexingTypesWithNever.ts, 115, 21)) + +type Res3 = Example; // never +>Res3 : Symbol(Res3, Decl(indexingTypesWithNever.ts, 115, 32)) +>Example : Symbol(Example, Decl(indexingTypesWithNever.ts, 108, 46)) + diff --git a/tests/baselines/reference/indexingTypesWithNever.types b/tests/baselines/reference/indexingTypesWithNever.types index 52583a73ba598..d6a97df222520 100644 --- a/tests/baselines/reference/indexingTypesWithNever.types +++ b/tests/baselines/reference/indexingTypesWithNever.types @@ -264,3 +264,20 @@ declare const o1Test: ExpectType<{}, O1Props>; declare const o0Test: ExpectType<{}, O0Props>; >o0Test : "Match" +// Repro from #23005 + +type Example> = T['a']; +>Example : T["a"] + +type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y" +>Res1 : "x" | "y" +>a : "x" +>a : "y" + +type Res2 = Example<{ a: "x" }>; // "x" +>Res2 : "x" +>a : "x" + +type Res3 = Example; // never +>Res3 : never +