Skip to content

Commit 5ba678a

Browse files
authored
Merge pull request #12480 from Microsoft/keyofIsLiteralContext
Make 'keyof T' a literal contextual type
2 parents e128add + 2cec4c5 commit 5ba678a

File tree

4 files changed

+69
-1
lines changed

4 files changed

+69
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14870,7 +14870,7 @@ namespace ts {
1487014870
}
1487114871
contextualType = apparentType;
1487214872
}
14873-
return maybeTypeOfKind(contextualType, TypeFlags.Literal);
14873+
return maybeTypeOfKind(contextualType, (TypeFlags.Literal | TypeFlags.Index));
1487414874
}
1487514875
return false;
1487614876
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
tests/cases/compiler/keyofIsLiteralContexualType.ts(5,9): error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
2+
Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
3+
Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
4+
Type '"c"' is not assignable to type '"a" | "b"'.
5+
Type '"c"' is not assignable to type 'keyof T'.
6+
Type '"c"' is not assignable to type '"a" | "b"'.
7+
tests/cases/compiler/keyofIsLiteralContexualType.ts(13,11): error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
8+
9+
10+
==== tests/cases/compiler/keyofIsLiteralContexualType.ts (2 errors) ====
11+
// keyof T is a literal contextual type
12+
13+
function foo<T extends { a: string, b: string }>() {
14+
let a: (keyof T)[] = ["a", "b"];
15+
let b: (keyof T)[] = ["a", "b", "c"];
16+
~
17+
!!! error TS2322: Type '("a" | "b" | "c")[]' is not assignable to type 'keyof T[]'.
18+
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type 'keyof T'.
19+
!!! error TS2322: Type '"a" | "b" | "c"' is not assignable to type '"a" | "b"'.
20+
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
21+
!!! error TS2322: Type '"c"' is not assignable to type 'keyof T'.
22+
!!! error TS2322: Type '"c"' is not assignable to type '"a" | "b"'.
23+
}
24+
25+
// Repro from #12455
26+
27+
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
28+
29+
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
30+
let b = x.b; // Error
31+
~
32+
!!! error TS2339: Property 'b' does not exist on type 'Pick<{ a: number; b: number; c: number; }, "a" | "c">'.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [keyofIsLiteralContexualType.ts]
2+
// keyof T is a literal contextual type
3+
4+
function foo<T extends { a: string, b: string }>() {
5+
let a: (keyof T)[] = ["a", "b"];
6+
let b: (keyof T)[] = ["a", "b", "c"];
7+
}
8+
9+
// Repro from #12455
10+
11+
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
12+
13+
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
14+
let b = x.b; // Error
15+
16+
//// [keyofIsLiteralContexualType.js]
17+
// keyof T is a literal contextual type
18+
function foo() {
19+
var a = ["a", "b"];
20+
var b = ["a", "b", "c"];
21+
}
22+
var x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
23+
var b = x.b; // Error
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// keyof T is a literal contextual type
2+
3+
function foo<T extends { a: string, b: string }>() {
4+
let a: (keyof T)[] = ["a", "b"];
5+
let b: (keyof T)[] = ["a", "b", "c"];
6+
}
7+
8+
// Repro from #12455
9+
10+
declare function pick<T, K extends keyof T>(obj: T, propNames: K[]): Pick<T, K>;
11+
12+
let x = pick({ a: 10, b: 20, c: 30 }, ["a", "c"]);
13+
let b = x.b; // Error

0 commit comments

Comments
 (0)