Skip to content
This repository was archived by the owner on Jan 13, 2024. It is now read-only.

Commit 4b0f54f

Browse files
authored
Fixed cache key computation for tuple target types with partially named members (microsoft#55695)
1 parent 4f899a1 commit 4b0f54f

File tree

5 files changed

+190
-2
lines changed

5 files changed

+190
-2
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16392,10 +16392,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1639216392
// [...X[]] is equivalent to just X[]
1639316393
return readonly ? globalReadonlyArrayType : globalArrayType;
1639416394
}
16395-
const memberIds = mapDefined(namedMemberDeclarations, node => node ? getNodeId(node) : undefined);
1639616395
const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() +
1639716396
(readonly ? "R" : "") +
16398-
(memberIds.length ? "," + memberIds.join(",") : "");
16397+
(some(namedMemberDeclarations, node => !!node) ? "," + map(namedMemberDeclarations, node => node ? getNodeId(node) : "_").join(",") : "");
1639916398
let type = tupleTypes.get(key);
1640016399
if (!type) {
1640116400
tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations));
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
2+
3+
//// [partiallyNamedTuples2.ts]
4+
// https://github.com/microsoft/TypeScript/issues/55693
5+
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
6+
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
7+
}
8+
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
9+
...infer Remain,
10+
infer _,
11+
]
12+
? Keys | GetKeys<Remain>
13+
: Keys;
14+
type GetResult<
15+
Id extends readonly unknown[],
16+
Args extends GetKeys<Id>,
17+
Value,
18+
> = Args extends Id
19+
? Value | undefined
20+
: Id extends [...Args, ...infer Rest]
21+
? Iterable<[...Rest, Value]>
22+
: never;
23+
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
24+
const id1 = "abc" as string;
25+
const matches = x.get(id1);
26+
27+
28+
//// [partiallyNamedTuples2.js]
29+
"use strict";
30+
var x = null;
31+
var id1 = "abc";
32+
var matches = x.get(id1);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
2+
3+
=== partiallyNamedTuples2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/55693
5+
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
6+
>MultiKeyMap : Symbol(MultiKeyMap, Decl(partiallyNamedTuples2.ts, 0, 0))
7+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
8+
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 1, 54))
9+
10+
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
11+
>get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
12+
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
13+
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
14+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
15+
>key : Symbol(key, Decl(partiallyNamedTuples2.ts, 2, 33))
16+
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
17+
>GetResult : Symbol(GetResult, Decl(partiallyNamedTuples2.ts, 9, 9))
18+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
19+
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
20+
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 1, 54))
21+
}
22+
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
23+
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
24+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
25+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
26+
27+
...infer Remain,
28+
>Remain : Symbol(Remain, Decl(partiallyNamedTuples2.ts, 5, 10))
29+
30+
infer _,
31+
>_ : Symbol(_, Decl(partiallyNamedTuples2.ts, 6, 7))
32+
33+
]
34+
? Keys | GetKeys<Remain>
35+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
36+
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
37+
>Remain : Symbol(Remain, Decl(partiallyNamedTuples2.ts, 5, 10))
38+
39+
: Keys;
40+
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
41+
42+
type GetResult<
43+
>GetResult : Symbol(GetResult, Decl(partiallyNamedTuples2.ts, 9, 9))
44+
45+
Id extends readonly unknown[],
46+
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
47+
48+
Args extends GetKeys<Id>,
49+
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
50+
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
51+
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
52+
53+
Value,
54+
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
55+
56+
> = Args extends Id
57+
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
58+
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
59+
60+
? Value | undefined
61+
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
62+
63+
: Id extends [...Args, ...infer Rest]
64+
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
65+
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
66+
>Rest : Symbol(Rest, Decl(partiallyNamedTuples2.ts, 16, 33))
67+
68+
? Iterable<[...Rest, Value]>
69+
>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --))
70+
>Rest : Symbol(Rest, Decl(partiallyNamedTuples2.ts, 16, 33))
71+
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
72+
73+
: never;
74+
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
75+
>x : Symbol(x, Decl(partiallyNamedTuples2.ts, 19, 5))
76+
>MultiKeyMap : Symbol(MultiKeyMap, Decl(partiallyNamedTuples2.ts, 0, 0))
77+
78+
const id1 = "abc" as string;
79+
>id1 : Symbol(id1, Decl(partiallyNamedTuples2.ts, 20, 5))
80+
81+
const matches = x.get(id1);
82+
>matches : Symbol(matches, Decl(partiallyNamedTuples2.ts, 21, 5))
83+
>x.get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
84+
>x : Symbol(x, Decl(partiallyNamedTuples2.ts, 19, 5))
85+
>get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
86+
>id1 : Symbol(id1, Decl(partiallyNamedTuples2.ts, 20, 5))
87+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
2+
3+
=== partiallyNamedTuples2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/55693
5+
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
6+
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
7+
>get : <Key extends GetKeys<Keys>>(...key: Key) => GetResult<Keys, Key, Value>
8+
>key : Key
9+
}
10+
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
11+
>GetKeys : GetKeys<Keys>
12+
13+
...infer Remain,
14+
infer _,
15+
]
16+
? Keys | GetKeys<Remain>
17+
: Keys;
18+
type GetResult<
19+
>GetResult : GetResult<Id, Args, Value>
20+
21+
Id extends readonly unknown[],
22+
Args extends GetKeys<Id>,
23+
Value,
24+
> = Args extends Id
25+
? Value | undefined
26+
: Id extends [...Args, ...infer Rest]
27+
? Iterable<[...Rest, Value]>
28+
: never;
29+
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
30+
>x : MultiKeyMap<[id1: string, id2: string], object>
31+
>null! : never
32+
33+
const id1 = "abc" as string;
34+
>id1 : string
35+
>"abc" as string : string
36+
>"abc" : "abc"
37+
38+
const matches = x.get(id1);
39+
>matches : Iterable<[id2: string, object]>
40+
>x.get(id1) : Iterable<[id2: string, object]>
41+
>x.get : <Key extends [id1: string, id2: string] | [id1: string] | []>(...key: Key) => GetResult<[id1: string, id2: string], Key, object>
42+
>x : MultiKeyMap<[id1: string, id2: string], object>
43+
>get : <Key extends [id1: string, id2: string] | [id1: string] | []>(...key: Key) => GetResult<[id1: string, id2: string], Key, object>
44+
>id1 : string
45+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @strict: true
2+
// @lib: esnext
3+
4+
// https://github.com/microsoft/TypeScript/issues/55693
5+
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
6+
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
7+
}
8+
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
9+
...infer Remain,
10+
infer _,
11+
]
12+
? Keys | GetKeys<Remain>
13+
: Keys;
14+
type GetResult<
15+
Id extends readonly unknown[],
16+
Args extends GetKeys<Id>,
17+
Value,
18+
> = Args extends Id
19+
? Value | undefined
20+
: Id extends [...Args, ...infer Rest]
21+
? Iterable<[...Rest, Value]>
22+
: never;
23+
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
24+
const id1 = "abc" as string;
25+
const matches = x.get(id1);

0 commit comments

Comments
 (0)