Skip to content

Commit

Permalink
Merge pull request #26340 from Microsoft/neverIndexedAccess
Browse files Browse the repository at this point in the history
T[K] should be 'never' when T is 'never'
  • Loading branch information
ahejlsberg committed Aug 15, 2018
2 parents 969b46e + df2af29 commit 178f792
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9149,7 +9149,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) ||
Expand Down
8 changes: 8 additions & 0 deletions tests/baselines/reference/indexingTypesWithNever.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 extends Record<'a', string>> = T['a'];

type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y"
type Res2 = Example<{ a: "x" }>; // "x"
type Res3 = Example<never>; // never


//// [indexingTypesWithNever.js]
Expand Down
23 changes: 23 additions & 0 deletions tests/baselines/reference/indexingTypesWithNever.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -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 extends Record<'a', string>> = 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>; // never
>Res3 : Symbol(Res3, Decl(indexingTypesWithNever.ts, 115, 32))
>Example : Symbol(Example, Decl(indexingTypesWithNever.ts, 108, 46))

17 changes: 17 additions & 0 deletions tests/baselines/reference/indexingTypesWithNever.types
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,20 @@ declare const o1Test: ExpectType<{}, O1Props>;
declare const o0Test: ExpectType<{}, O0Props>;
>o0Test : "Match"

// Repro from #23005

type Example<T extends Record<'a', string>> = 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>; // never
>Res3 : never

Original file line number Diff line number Diff line change
Expand Up @@ -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]'.
Expand Down Expand Up @@ -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<T extends number, P extends keyof T>(s: string, tp: T[P]): void {
tp = s;
Expand Down
8 changes: 8 additions & 0 deletions tests/cases/compiler/indexingTypesWithNever.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 extends Record<'a', string>> = T['a'];

type Res1 = Example<{ a: "x" } | { a: "y" }>; // "x" | "y"
type Res2 = Example<{ a: "x" }>; // "x"
type Res3 = Example<never>; // never

0 comments on commit 178f792

Please sign in to comment.