Fixed cache key computation for tuple target types with partially named members (#55695)

This commit is contained in:
Mateusz Burzyński 2023-09-11 23:41:08 +02:00 committed by GitHub
parent 4f899a1691
commit 4b0f54fe9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 190 additions and 2 deletions

View File

@ -16392,10 +16392,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// [...X[]] is equivalent to just X[]
return readonly ? globalReadonlyArrayType : globalArrayType;
}
const memberIds = mapDefined(namedMemberDeclarations, node => node ? getNodeId(node) : undefined);
const key = map(elementFlags, f => f & ElementFlags.Required ? "#" : f & ElementFlags.Optional ? "?" : f & ElementFlags.Rest ? "." : "*").join() +
(readonly ? "R" : "") +
(memberIds.length ? "," + memberIds.join(",") : "");
(some(namedMemberDeclarations, node => !!node) ? "," + map(namedMemberDeclarations, node => node ? getNodeId(node) : "_").join(",") : "");
let type = tupleTypes.get(key);
if (!type) {
tupleTypes.set(key, type = createTupleTargetType(elementFlags, readonly, namedMemberDeclarations));

View File

@ -0,0 +1,32 @@
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
//// [partiallyNamedTuples2.ts]
// https://github.com/microsoft/TypeScript/issues/55693
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
}
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
...infer Remain,
infer _,
]
? Keys | GetKeys<Remain>
: Keys;
type GetResult<
Id extends readonly unknown[],
Args extends GetKeys<Id>,
Value,
> = Args extends Id
? Value | undefined
: Id extends [...Args, ...infer Rest]
? Iterable<[...Rest, Value]>
: never;
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
const id1 = "abc" as string;
const matches = x.get(id1);
//// [partiallyNamedTuples2.js]
"use strict";
var x = null;
var id1 = "abc";
var matches = x.get(id1);

View File

@ -0,0 +1,87 @@
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
=== partiallyNamedTuples2.ts ===
// https://github.com/microsoft/TypeScript/issues/55693
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
>MultiKeyMap : Symbol(MultiKeyMap, Decl(partiallyNamedTuples2.ts, 0, 0))
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 1, 54))
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
>get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
>key : Symbol(key, Decl(partiallyNamedTuples2.ts, 2, 33))
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
>GetResult : Symbol(GetResult, Decl(partiallyNamedTuples2.ts, 9, 9))
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 1, 22))
>Key : Symbol(Key, Decl(partiallyNamedTuples2.ts, 2, 6))
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 1, 54))
}
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
...infer Remain,
>Remain : Symbol(Remain, Decl(partiallyNamedTuples2.ts, 5, 10))
infer _,
>_ : Symbol(_, Decl(partiallyNamedTuples2.ts, 6, 7))
]
? Keys | GetKeys<Remain>
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
>Remain : Symbol(Remain, Decl(partiallyNamedTuples2.ts, 5, 10))
: Keys;
>Keys : Symbol(Keys, Decl(partiallyNamedTuples2.ts, 4, 13))
type GetResult<
>GetResult : Symbol(GetResult, Decl(partiallyNamedTuples2.ts, 9, 9))
Id extends readonly unknown[],
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
Args extends GetKeys<Id>,
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
>GetKeys : Symbol(GetKeys, Decl(partiallyNamedTuples2.ts, 3, 1))
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
Value,
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
> = Args extends Id
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
? Value | undefined
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
: Id extends [...Args, ...infer Rest]
>Id : Symbol(Id, Decl(partiallyNamedTuples2.ts, 10, 15))
>Args : Symbol(Args, Decl(partiallyNamedTuples2.ts, 11, 32))
>Rest : Symbol(Rest, Decl(partiallyNamedTuples2.ts, 16, 33))
? Iterable<[...Rest, Value]>
>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --))
>Rest : Symbol(Rest, Decl(partiallyNamedTuples2.ts, 16, 33))
>Value : Symbol(Value, Decl(partiallyNamedTuples2.ts, 12, 27))
: never;
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
>x : Symbol(x, Decl(partiallyNamedTuples2.ts, 19, 5))
>MultiKeyMap : Symbol(MultiKeyMap, Decl(partiallyNamedTuples2.ts, 0, 0))
const id1 = "abc" as string;
>id1 : Symbol(id1, Decl(partiallyNamedTuples2.ts, 20, 5))
const matches = x.get(id1);
>matches : Symbol(matches, Decl(partiallyNamedTuples2.ts, 21, 5))
>x.get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
>x : Symbol(x, Decl(partiallyNamedTuples2.ts, 19, 5))
>get : Symbol(MultiKeyMap.get, Decl(partiallyNamedTuples2.ts, 1, 63))
>id1 : Symbol(id1, Decl(partiallyNamedTuples2.ts, 20, 5))

View File

@ -0,0 +1,45 @@
//// [tests/cases/conformance/types/tuple/named/partiallyNamedTuples2.ts] ////
=== partiallyNamedTuples2.ts ===
// https://github.com/microsoft/TypeScript/issues/55693
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
>get : <Key extends GetKeys<Keys>>(...key: Key) => GetResult<Keys, Key, Value>
>key : Key
}
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
>GetKeys : GetKeys<Keys>
...infer Remain,
infer _,
]
? Keys | GetKeys<Remain>
: Keys;
type GetResult<
>GetResult : GetResult<Id, Args, Value>
Id extends readonly unknown[],
Args extends GetKeys<Id>,
Value,
> = Args extends Id
? Value | undefined
: Id extends [...Args, ...infer Rest]
? Iterable<[...Rest, Value]>
: never;
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
>x : MultiKeyMap<[id1: string, id2: string], object>
>null! : never
const id1 = "abc" as string;
>id1 : string
>"abc" as string : string
>"abc" : "abc"
const matches = x.get(id1);
>matches : Iterable<[id2: string, object]>
>x.get(id1) : Iterable<[id2: string, object]>
>x.get : <Key extends [id1: string, id2: string] | [id1: string] | []>(...key: Key) => GetResult<[id1: string, id2: string], Key, object>
>x : MultiKeyMap<[id1: string, id2: string], object>
>get : <Key extends [id1: string, id2: string] | [id1: string] | []>(...key: Key) => GetResult<[id1: string, id2: string], Key, object>
>id1 : string

View File

@ -0,0 +1,25 @@
// @strict: true
// @lib: esnext
// https://github.com/microsoft/TypeScript/issues/55693
interface MultiKeyMap<Keys extends readonly unknown[], Value> {
get<Key extends GetKeys<Keys>>(...key: Key): GetResult<Keys, Key, Value>;
}
type GetKeys<Keys extends readonly unknown[]> = Keys extends [
...infer Remain,
infer _,
]
? Keys | GetKeys<Remain>
: Keys;
type GetResult<
Id extends readonly unknown[],
Args extends GetKeys<Id>,
Value,
> = Args extends Id
? Value | undefined
: Id extends [...Args, ...infer Rest]
? Iterable<[...Rest, Value]>
: never;
const x: MultiKeyMap<[id1: string, id2: string], object> = null!;
const id1 = "abc" as string;
const matches = x.get(id1);