mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Fix check in isMappedTypeGenericIndexedAccess (#49341)
* Fix check in isMappedTypeGenericIndexedAccess * Add regression tests
This commit is contained in:
parent
9031497b92
commit
1beb1037c0
@ -12308,7 +12308,7 @@ namespace ts {
|
||||
let objectType;
|
||||
return !!(type.flags & TypeFlags.IndexedAccess && getObjectFlags(objectType = (type as IndexedAccessType).objectType) & ObjectFlags.Mapped &&
|
||||
!isGenericMappedType(objectType) && isGenericIndexType((type as IndexedAccessType).indexType) &&
|
||||
!(objectType as MappedType).declaration.questionToken && !(objectType as MappedType).declaration.nameType);
|
||||
!(getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.ExcludeOptional) && !(objectType as MappedType).declaration.nameType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
105
tests/baselines/reference/mappedTypeGenericIndexedAccess.js
Normal file
105
tests/baselines/reference/mappedTypeGenericIndexedAccess.js
Normal file
@ -0,0 +1,105 @@
|
||||
//// [mappedTypeGenericIndexedAccess.ts]
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
first: { a1: true };
|
||||
second: { a2: true };
|
||||
third: { a3: true };
|
||||
}
|
||||
|
||||
class Test {
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
if (!this.entries[name]) {
|
||||
this.entries[name] = [];
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
[0]: { foo: 'bar'; };
|
||||
[1]: { a: 'b'; };
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
|
||||
type TypeHandlers = {
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
[0]: (p) => console.log(p.foo),
|
||||
[1]: (p) => console.log(p.a),
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
typeHandlers[p.t]?.(p);
|
||||
|
||||
|
||||
//// [mappedTypeGenericIndexedAccess.js]
|
||||
"use strict";
|
||||
// Repro from #49242
|
||||
var _a;
|
||||
var Test = /** @class */ (function () {
|
||||
function Test() {
|
||||
this.entries = {};
|
||||
}
|
||||
Test.prototype.addEntry = function (name, entry) {
|
||||
var _a;
|
||||
if (!this.entries[name]) {
|
||||
this.entries[name] = [];
|
||||
}
|
||||
(_a = this.entries[name]) === null || _a === void 0 ? void 0 : _a.push(entry);
|
||||
};
|
||||
return Test;
|
||||
}());
|
||||
var typeHandlers = (_a = {},
|
||||
_a[0] = function (p) { return console.log(p.foo); },
|
||||
_a[1] = function (p) { return console.log(p.a); },
|
||||
_a);
|
||||
var onSomeEvent = function (p) { var _a; return (_a = typeHandlers[p.t]) === null || _a === void 0 ? void 0 : _a.call(typeHandlers, p); };
|
||||
|
||||
|
||||
//// [mappedTypeGenericIndexedAccess.d.ts]
|
||||
declare type Types = {
|
||||
first: {
|
||||
a1: true;
|
||||
};
|
||||
second: {
|
||||
a2: true;
|
||||
};
|
||||
third: {
|
||||
a3: true;
|
||||
};
|
||||
};
|
||||
declare class Test {
|
||||
entries: {
|
||||
[T in keyof Types]?: Types[T][];
|
||||
};
|
||||
constructor();
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]): void;
|
||||
}
|
||||
declare type TypesMap = {
|
||||
[0]: {
|
||||
foo: 'bar';
|
||||
};
|
||||
[1]: {
|
||||
a: 'b';
|
||||
};
|
||||
};
|
||||
declare type P<T extends keyof TypesMap> = {
|
||||
t: T;
|
||||
} & TypesMap[T];
|
||||
declare type TypeHandlers = {
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
};
|
||||
declare const typeHandlers: TypeHandlers;
|
||||
declare const onSomeEvent: <T extends keyof TypesMap>(p: P<T>) => void | undefined;
|
||||
150
tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols
Normal file
150
tests/baselines/reference/mappedTypeGenericIndexedAccess.symbols
Normal file
@ -0,0 +1,150 @@
|
||||
=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts ===
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
|
||||
first: { a1: true };
|
||||
>first : Symbol(first, Decl(mappedTypeGenericIndexedAccess.ts, 2, 14))
|
||||
>a1 : Symbol(a1, Decl(mappedTypeGenericIndexedAccess.ts, 3, 12))
|
||||
|
||||
second: { a2: true };
|
||||
>second : Symbol(second, Decl(mappedTypeGenericIndexedAccess.ts, 3, 24))
|
||||
>a2 : Symbol(a2, Decl(mappedTypeGenericIndexedAccess.ts, 4, 13))
|
||||
|
||||
third: { a3: true };
|
||||
>third : Symbol(third, Decl(mappedTypeGenericIndexedAccess.ts, 4, 25))
|
||||
>a3 : Symbol(a3, Decl(mappedTypeGenericIndexedAccess.ts, 5, 12))
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 9, 16))
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
>addEntry : Symbol(Test.addEntry, Decl(mappedTypeGenericIndexedAccess.ts, 13, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44))
|
||||
>Types : Symbol(Types, Decl(mappedTypeGenericIndexedAccess.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 15, 13))
|
||||
|
||||
if (!this.entries[name]) {
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
|
||||
this.entries[name] = [];
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
>this.entries[name]?.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>this.entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>this : Symbol(Test, Decl(mappedTypeGenericIndexedAccess.ts, 6, 1))
|
||||
>entries : Symbol(Test.entries, Decl(mappedTypeGenericIndexedAccess.ts, 8, 12))
|
||||
>name : Symbol(name, Decl(mappedTypeGenericIndexedAccess.ts, 15, 36))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>entry : Symbol(entry, Decl(mappedTypeGenericIndexedAccess.ts, 15, 44))
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
|
||||
[0]: { foo: 'bar'; };
|
||||
>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17))
|
||||
>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 25, 17))
|
||||
>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
|
||||
[1]: { a: 'b'; };
|
||||
>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25))
|
||||
>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 26, 25))
|
||||
>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 30, 7))
|
||||
|
||||
type TypeHandlers = {
|
||||
>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59))
|
||||
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 33, 29))
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 33, 5))
|
||||
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5))
|
||||
>TypeHandlers : Symbol(TypeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 30, 59))
|
||||
|
||||
[0]: (p) => console.log(p.foo),
|
||||
>[0] : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36))
|
||||
>0 : Symbol([0], Decl(mappedTypeGenericIndexedAccess.ts, 36, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>p.foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 37, 10))
|
||||
>foo : Symbol(foo, Decl(mappedTypeGenericIndexedAccess.ts, 26, 10))
|
||||
|
||||
[1]: (p) => console.log(p.a),
|
||||
>[1] : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35))
|
||||
>1 : Symbol([1], Decl(mappedTypeGenericIndexedAccess.ts, 37, 35))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>p.a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 38, 10))
|
||||
>a : Symbol(a, Decl(mappedTypeGenericIndexedAccess.ts, 27, 10))
|
||||
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
>onSomeEvent : Symbol(onSomeEvent, Decl(mappedTypeGenericIndexedAccess.ts, 41, 5))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21))
|
||||
>TypesMap : Symbol(TypesMap, Decl(mappedTypeGenericIndexedAccess.ts, 21, 1))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
>P : Symbol(P, Decl(mappedTypeGenericIndexedAccess.ts, 28, 2))
|
||||
>T : Symbol(T, Decl(mappedTypeGenericIndexedAccess.ts, 41, 21))
|
||||
|
||||
typeHandlers[p.t]?.(p);
|
||||
>typeHandlers : Symbol(typeHandlers, Decl(mappedTypeGenericIndexedAccess.ts, 36, 5))
|
||||
>p.t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
>t : Symbol(t, Decl(mappedTypeGenericIndexedAccess.ts, 30, 36))
|
||||
>p : Symbol(p, Decl(mappedTypeGenericIndexedAccess.ts, 41, 47))
|
||||
|
||||
147
tests/baselines/reference/mappedTypeGenericIndexedAccess.types
Normal file
147
tests/baselines/reference/mappedTypeGenericIndexedAccess.types
Normal file
@ -0,0 +1,147 @@
|
||||
=== tests/cases/compiler/mappedTypeGenericIndexedAccess.ts ===
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
>Types : { first: { a1: true;}; second: { a2: true;}; third: { a3: true;}; }
|
||||
|
||||
first: { a1: true };
|
||||
>first : { a1: true; }
|
||||
>a1 : true
|
||||
>true : true
|
||||
|
||||
second: { a2: true };
|
||||
>second : { a2: true; }
|
||||
>a2 : true
|
||||
>true : true
|
||||
|
||||
third: { a3: true };
|
||||
>third : { a3: true; }
|
||||
>a3 : true
|
||||
>true : true
|
||||
}
|
||||
|
||||
class Test {
|
||||
>Test : Test
|
||||
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
>this.entries = {} : {}
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>{} : {}
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
>addEntry : <T extends keyof Types>(name: T, entry: Types[T]) => void
|
||||
>name : T
|
||||
>entry : Types[T]
|
||||
|
||||
if (!this.entries[name]) {
|
||||
>!this.entries[name] : boolean
|
||||
>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T]
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
|
||||
this.entries[name] = [];
|
||||
>this.entries[name] = [] : never[]
|
||||
>this.entries[name] : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }[T]
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
>[] : never[]
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
>this.entries[name]?.push(entry) : number | undefined
|
||||
>this.entries[name]?.push : ((...items: Types[T][]) => number) | undefined
|
||||
>this.entries[name] : Types[T][] | undefined
|
||||
>this.entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>this : this
|
||||
>entries : { first?: { a1: true; }[] | undefined; second?: { a2: true; }[] | undefined; third?: { a3: true; }[] | undefined; }
|
||||
>name : T
|
||||
>push : ((...items: Types[T][]) => number) | undefined
|
||||
>entry : Types[T]
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
>TypesMap : { 0: { foo: 'bar';}; 1: { a: 'b';}; }
|
||||
|
||||
[0]: { foo: 'bar'; };
|
||||
>[0] : { foo: 'bar'; }
|
||||
>0 : 0
|
||||
>foo : "bar"
|
||||
|
||||
[1]: { a: 'b'; };
|
||||
>[1] : { a: 'b'; }
|
||||
>1 : 1
|
||||
>a : "b"
|
||||
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
>P : P<T>
|
||||
>t : T
|
||||
|
||||
type TypeHandlers = {
|
||||
>TypeHandlers : { 0?: ((p: P<0>) => void) | undefined; 1?: ((p: P<1>) => void) | undefined; }
|
||||
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
>p : P<T>
|
||||
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
>typeHandlers : TypeHandlers
|
||||
>{ [0]: (p) => console.log(p.foo), [1]: (p) => console.log(p.a),} : { 0: (p: P<0>) => void; 1: (p: P<1>) => void; }
|
||||
|
||||
[0]: (p) => console.log(p.foo),
|
||||
>[0] : (p: P<0>) => void
|
||||
>0 : 0
|
||||
>(p) => console.log(p.foo) : (p: P<0>) => void
|
||||
>p : P<0>
|
||||
>console.log(p.foo) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>p.foo : "bar"
|
||||
>p : P<0>
|
||||
>foo : "bar"
|
||||
|
||||
[1]: (p) => console.log(p.a),
|
||||
>[1] : (p: P<1>) => void
|
||||
>1 : 1
|
||||
>(p) => console.log(p.a) : (p: P<1>) => void
|
||||
>p : P<1>
|
||||
>console.log(p.a) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
>p.a : "b"
|
||||
>p : P<1>
|
||||
>a : "b"
|
||||
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
>onSomeEvent : <T extends keyof TypesMap>(p: P<T>) => void | undefined
|
||||
><T extends keyof TypesMap>(p: P<T>) => typeHandlers[p.t]?.(p) : <T extends keyof TypesMap>(p: P<T>) => void | undefined
|
||||
>p : P<T>
|
||||
|
||||
typeHandlers[p.t]?.(p);
|
||||
>typeHandlers[p.t]?.(p) : void | undefined
|
||||
>typeHandlers[p.t] : ((p: P<T>) => void) | undefined
|
||||
>typeHandlers : TypeHandlers
|
||||
>p.t : T
|
||||
>p : { t: T; } & ({ foo: "bar"; } | { a: "b"; })
|
||||
>t : T
|
||||
>p : P<T>
|
||||
|
||||
46
tests/cases/compiler/mappedTypeGenericIndexedAccess.ts
Normal file
46
tests/cases/compiler/mappedTypeGenericIndexedAccess.ts
Normal file
@ -0,0 +1,46 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// Repro from #49242
|
||||
|
||||
type Types = {
|
||||
first: { a1: true };
|
||||
second: { a2: true };
|
||||
third: { a3: true };
|
||||
}
|
||||
|
||||
class Test {
|
||||
entries: { [T in keyof Types]?: Types[T][] };
|
||||
|
||||
constructor() {
|
||||
this.entries = {};
|
||||
}
|
||||
|
||||
addEntry<T extends keyof Types>(name: T, entry: Types[T]) {
|
||||
if (!this.entries[name]) {
|
||||
this.entries[name] = [];
|
||||
}
|
||||
this.entries[name]?.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
// Repro from #49338
|
||||
|
||||
type TypesMap = {
|
||||
[0]: { foo: 'bar'; };
|
||||
[1]: { a: 'b'; };
|
||||
};
|
||||
|
||||
type P<T extends keyof TypesMap> = { t: T; } & TypesMap[T];
|
||||
|
||||
type TypeHandlers = {
|
||||
[T in keyof TypesMap]?: (p: P<T>) => void;
|
||||
};
|
||||
|
||||
const typeHandlers: TypeHandlers = {
|
||||
[0]: (p) => console.log(p.foo),
|
||||
[1]: (p) => console.log(p.a),
|
||||
};
|
||||
|
||||
const onSomeEvent = <T extends keyof TypesMap>(p: P<T>) =>
|
||||
typeHandlers[p.t]?.(p);
|
||||
Loading…
x
Reference in New Issue
Block a user