diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0b67afefbb9d8..7f693faac9495 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17729,7 +17729,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // eagerly using the constraint type of 'this' at the given location. if (isGenericIndexType(indexType) || (accessNode && accessNode.kind !== SyntaxKind.IndexedAccessType ? isGenericTupleType(objectType) && !indexTypeLessThan(indexType, objectType.target.fixedLength) : - isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)) || isGenericReducibleType(objectType))) { + isGenericObjectType(objectType) && !(isTupleType(objectType) && indexTypeLessThan(indexType, objectType.target.fixedLength)) || !(accessFlags & AccessFlags.Writing) && isGenericReducibleType(objectType))) { if (objectType.flags & TypeFlags.AnyOrUnknown) { return objectType; } diff --git a/tests/baselines/reference/correlatedUnions.js b/tests/baselines/reference/correlatedUnions.js index 5335811054601..9a8d000bb6aac 100644 --- a/tests/baselines/reference/correlatedUnions.js +++ b/tests/baselines/reference/correlatedUnions.js @@ -301,6 +301,79 @@ function getValueConcrete( ): Foo1[K] | undefined { return o[k]; } + +// repro from https://github.com/microsoft/TypeScript/issues/54680 + +type A_54680 = { + type: "A"; + value: string; +}; + +type B_54680 = { + type: "B"; + value: number; +}; + +type Message_54680 = A_54680 | B_54680; + +function handle_54680_1(callbacks: { + [K in M["type"]]: (msg: Extract["value"]) => unknown; +}) { + window.addEventListener("message", (event) => { + const msg = event.data as M; + callbacks[msg.type as keyof typeof callbacks](msg.value); + }); +} + +function handle_54680_2(callbacks: { + [K in M["type"]]: (msg: (M & { type: K })["value"]) => unknown; +}) { + window.addEventListener("message", (event) => { + const msg = event.data as M; + callbacks[msg.type as keyof typeof callbacks](msg.value); + }); +} + +// repro from https://github.com/microsoft/TypeScript/issues/54834 + +type NumericLiteral_54834 = { + value: number; + type: "NumericLiteral"; +}; +type StringLiteral_54834 = { + value: string; + type: "StringLiteral"; +}; +type Identifier_54834 = { + name: string; + type: "Identifier"; +}; +type CallExpression_54834 = { + name: string; + arguments: DropbearNode_54834[]; + type: "CallExpression"; +}; + +type DropbearNode_54834 = + | NumericLiteral_54834 + | StringLiteral_54834 + | Identifier_54834 + | CallExpression_54834; + +type TypeMap_54834 = { + [K in DropbearNode_54834["type"]]: Extract; +}; + +type Visitor_54834 = { + [K in keyof TypeMap_54834]: (node: Readonly) => void; +}; + +function visitNode_54834( + node: Readonly, + v: Visitor_54834 +) { + v[node.type](node); +} //// [correlatedUnions.js] @@ -433,6 +506,21 @@ function getConfigOrDefault(userConfig, key, defaultValue) { function getValueConcrete(o, k) { return o[k]; } +function handle_54680_1(callbacks) { + window.addEventListener("message", function (event) { + var msg = event.data; + callbacks[msg.type](msg.value); + }); +} +function handle_54680_2(callbacks) { + window.addEventListener("message", function (event) { + var msg = event.data; + callbacks[msg.type](msg.value); + }); +} +function visitNode_54834(node, v) { + v[node.type](node); +} //// [correlatedUnions.d.ts] @@ -613,3 +701,49 @@ type Foo1 = { y: string; }; declare function getValueConcrete(o: Partial, k: K): Foo1[K] | undefined; +type A_54680 = { + type: "A"; + value: string; +}; +type B_54680 = { + type: "B"; + value: number; +}; +type Message_54680 = A_54680 | B_54680; +declare function handle_54680_1(callbacks: { + [K in M["type"]]: (msg: Extract["value"]) => unknown; +}): void; +declare function handle_54680_2(callbacks: { + [K in M["type"]]: (msg: (M & { + type: K; + })["value"]) => unknown; +}): void; +type NumericLiteral_54834 = { + value: number; + type: "NumericLiteral"; +}; +type StringLiteral_54834 = { + value: string; + type: "StringLiteral"; +}; +type Identifier_54834 = { + name: string; + type: "Identifier"; +}; +type CallExpression_54834 = { + name: string; + arguments: DropbearNode_54834[]; + type: "CallExpression"; +}; +type DropbearNode_54834 = NumericLiteral_54834 | StringLiteral_54834 | Identifier_54834 | CallExpression_54834; +type TypeMap_54834 = { + [K in DropbearNode_54834["type"]]: Extract; +}; +type Visitor_54834 = { + [K in keyof TypeMap_54834]: (node: Readonly) => void; +}; +declare function visitNode_54834(node: Readonly, v: Visitor_54834): void; diff --git a/tests/baselines/reference/correlatedUnions.symbols b/tests/baselines/reference/correlatedUnions.symbols index bf5fe9d678045..b4170c93b39c2 100644 --- a/tests/baselines/reference/correlatedUnions.symbols +++ b/tests/baselines/reference/correlatedUnions.symbols @@ -1016,3 +1016,227 @@ function getValueConcrete( >k : Symbol(k, Decl(correlatedUnions.ts, 295, 19)) } +// repro from https://github.com/microsoft/TypeScript/issues/54680 + +type A_54680 = { +>A_54680 : Symbol(A_54680, Decl(correlatedUnions.ts, 299, 1)) + + type: "A"; +>type : Symbol(type, Decl(correlatedUnions.ts, 303, 16)) + + value: string; +>value : Symbol(value, Decl(correlatedUnions.ts, 304, 12)) + +}; + +type B_54680 = { +>B_54680 : Symbol(B_54680, Decl(correlatedUnions.ts, 306, 2)) + + type: "B"; +>type : Symbol(type, Decl(correlatedUnions.ts, 308, 16)) + + value: number; +>value : Symbol(value, Decl(correlatedUnions.ts, 309, 12)) + +}; + +type Message_54680 = A_54680 | B_54680; +>Message_54680 : Symbol(Message_54680, Decl(correlatedUnions.ts, 311, 2)) +>A_54680 : Symbol(A_54680, Decl(correlatedUnions.ts, 299, 1)) +>B_54680 : Symbol(B_54680, Decl(correlatedUnions.ts, 306, 2)) + +function handle_54680_1(callbacks: { +>handle_54680_1 : Symbol(handle_54680_1, Decl(correlatedUnions.ts, 313, 39)) +>M : Symbol(M, Decl(correlatedUnions.ts, 315, 24)) +>Message_54680 : Symbol(Message_54680, Decl(correlatedUnions.ts, 311, 2)) +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 315, 49)) + + [K in M["type"]]: (msg: Extract["value"]) => unknown; +>K : Symbol(K, Decl(correlatedUnions.ts, 316, 3)) +>M : Symbol(M, Decl(correlatedUnions.ts, 315, 24)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 316, 21)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>M : Symbol(M, Decl(correlatedUnions.ts, 315, 24)) +>type : Symbol(type, Decl(correlatedUnions.ts, 316, 38)) +>K : Symbol(K, Decl(correlatedUnions.ts, 316, 3)) + +}) { + window.addEventListener("message", (event) => { +>window.addEventListener : Symbol(addEventListener, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>addEventListener : Symbol(addEventListener, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(correlatedUnions.ts, 318, 38)) + + const msg = event.data as M; +>msg : Symbol(msg, Decl(correlatedUnions.ts, 319, 9)) +>event.data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(correlatedUnions.ts, 318, 38)) +>data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>M : Symbol(M, Decl(correlatedUnions.ts, 315, 24)) + + callbacks[msg.type as keyof typeof callbacks](msg.value); +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 315, 49)) +>msg.type : Symbol(type, Decl(correlatedUnions.ts, 303, 16), Decl(correlatedUnions.ts, 308, 16)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 319, 9)) +>type : Symbol(type, Decl(correlatedUnions.ts, 303, 16), Decl(correlatedUnions.ts, 308, 16)) +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 315, 49)) +>msg.value : Symbol(value, Decl(correlatedUnions.ts, 304, 12), Decl(correlatedUnions.ts, 309, 12)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 319, 9)) +>value : Symbol(value, Decl(correlatedUnions.ts, 304, 12), Decl(correlatedUnions.ts, 309, 12)) + + }); +} + +function handle_54680_2(callbacks: { +>handle_54680_2 : Symbol(handle_54680_2, Decl(correlatedUnions.ts, 322, 1)) +>M : Symbol(M, Decl(correlatedUnions.ts, 324, 24)) +>Message_54680 : Symbol(Message_54680, Decl(correlatedUnions.ts, 311, 2)) +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 324, 49)) + + [K in M["type"]]: (msg: (M & { type: K })["value"]) => unknown; +>K : Symbol(K, Decl(correlatedUnions.ts, 325, 3)) +>M : Symbol(M, Decl(correlatedUnions.ts, 324, 24)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 325, 21)) +>M : Symbol(M, Decl(correlatedUnions.ts, 324, 24)) +>type : Symbol(type, Decl(correlatedUnions.ts, 325, 32)) +>K : Symbol(K, Decl(correlatedUnions.ts, 325, 3)) + +}) { + window.addEventListener("message", (event) => { +>window.addEventListener : Symbol(addEventListener, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>addEventListener : Symbol(addEventListener, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(correlatedUnions.ts, 327, 38)) + + const msg = event.data as M; +>msg : Symbol(msg, Decl(correlatedUnions.ts, 328, 9)) +>event.data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>event : Symbol(event, Decl(correlatedUnions.ts, 327, 38)) +>data : Symbol(MessageEvent.data, Decl(lib.dom.d.ts, --, --)) +>M : Symbol(M, Decl(correlatedUnions.ts, 324, 24)) + + callbacks[msg.type as keyof typeof callbacks](msg.value); +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 324, 49)) +>msg.type : Symbol(type, Decl(correlatedUnions.ts, 303, 16), Decl(correlatedUnions.ts, 308, 16)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 328, 9)) +>type : Symbol(type, Decl(correlatedUnions.ts, 303, 16), Decl(correlatedUnions.ts, 308, 16)) +>callbacks : Symbol(callbacks, Decl(correlatedUnions.ts, 324, 49)) +>msg.value : Symbol(value, Decl(correlatedUnions.ts, 304, 12), Decl(correlatedUnions.ts, 309, 12)) +>msg : Symbol(msg, Decl(correlatedUnions.ts, 328, 9)) +>value : Symbol(value, Decl(correlatedUnions.ts, 304, 12), Decl(correlatedUnions.ts, 309, 12)) + + }); +} + +// repro from https://github.com/microsoft/TypeScript/issues/54834 + +type NumericLiteral_54834 = { +>NumericLiteral_54834 : Symbol(NumericLiteral_54834, Decl(correlatedUnions.ts, 331, 1)) + + value: number; +>value : Symbol(value, Decl(correlatedUnions.ts, 335, 29)) + + type: "NumericLiteral"; +>type : Symbol(type, Decl(correlatedUnions.ts, 336, 16)) + +}; +type StringLiteral_54834 = { +>StringLiteral_54834 : Symbol(StringLiteral_54834, Decl(correlatedUnions.ts, 338, 2)) + + value: string; +>value : Symbol(value, Decl(correlatedUnions.ts, 339, 28)) + + type: "StringLiteral"; +>type : Symbol(type, Decl(correlatedUnions.ts, 340, 16)) + +}; +type Identifier_54834 = { +>Identifier_54834 : Symbol(Identifier_54834, Decl(correlatedUnions.ts, 342, 2)) + + name: string; +>name : Symbol(name, Decl(correlatedUnions.ts, 343, 25)) + + type: "Identifier"; +>type : Symbol(type, Decl(correlatedUnions.ts, 344, 15)) + +}; +type CallExpression_54834 = { +>CallExpression_54834 : Symbol(CallExpression_54834, Decl(correlatedUnions.ts, 346, 2)) + + name: string; +>name : Symbol(name, Decl(correlatedUnions.ts, 347, 29)) + + arguments: DropbearNode_54834[]; +>arguments : Symbol(arguments, Decl(correlatedUnions.ts, 348, 15)) +>DropbearNode_54834 : Symbol(DropbearNode_54834, Decl(correlatedUnions.ts, 351, 2)) + + type: "CallExpression"; +>type : Symbol(type, Decl(correlatedUnions.ts, 349, 34)) + +}; + +type DropbearNode_54834 = +>DropbearNode_54834 : Symbol(DropbearNode_54834, Decl(correlatedUnions.ts, 351, 2)) + + | NumericLiteral_54834 +>NumericLiteral_54834 : Symbol(NumericLiteral_54834, Decl(correlatedUnions.ts, 331, 1)) + + | StringLiteral_54834 +>StringLiteral_54834 : Symbol(StringLiteral_54834, Decl(correlatedUnions.ts, 338, 2)) + + | Identifier_54834 +>Identifier_54834 : Symbol(Identifier_54834, Decl(correlatedUnions.ts, 342, 2)) + + | CallExpression_54834; +>CallExpression_54834 : Symbol(CallExpression_54834, Decl(correlatedUnions.ts, 346, 2)) + +type TypeMap_54834 = { +>TypeMap_54834 : Symbol(TypeMap_54834, Decl(correlatedUnions.ts, 357, 25)) + + [K in DropbearNode_54834["type"]]: Extract; +>K : Symbol(K, Decl(correlatedUnions.ts, 360, 3)) +>DropbearNode_54834 : Symbol(DropbearNode_54834, Decl(correlatedUnions.ts, 351, 2)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>DropbearNode_54834 : Symbol(DropbearNode_54834, Decl(correlatedUnions.ts, 351, 2)) +>type : Symbol(type, Decl(correlatedUnions.ts, 360, 66)) +>K : Symbol(K, Decl(correlatedUnions.ts, 360, 3)) + +}; + +type Visitor_54834 = { +>Visitor_54834 : Symbol(Visitor_54834, Decl(correlatedUnions.ts, 361, 2)) + + [K in keyof TypeMap_54834]: (node: Readonly) => void; +>K : Symbol(K, Decl(correlatedUnions.ts, 364, 3)) +>TypeMap_54834 : Symbol(TypeMap_54834, Decl(correlatedUnions.ts, 357, 25)) +>node : Symbol(node, Decl(correlatedUnions.ts, 364, 31)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>TypeMap_54834 : Symbol(TypeMap_54834, Decl(correlatedUnions.ts, 357, 25)) +>K : Symbol(K, Decl(correlatedUnions.ts, 364, 3)) + +}; + +function visitNode_54834( +>visitNode_54834 : Symbol(visitNode_54834, Decl(correlatedUnions.ts, 365, 2)) +>K : Symbol(K, Decl(correlatedUnions.ts, 367, 25)) +>TypeMap_54834 : Symbol(TypeMap_54834, Decl(correlatedUnions.ts, 357, 25)) + + node: Readonly, +>node : Symbol(node, Decl(correlatedUnions.ts, 367, 56)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>TypeMap_54834 : Symbol(TypeMap_54834, Decl(correlatedUnions.ts, 357, 25)) +>K : Symbol(K, Decl(correlatedUnions.ts, 367, 25)) + + v: Visitor_54834 +>v : Symbol(v, Decl(correlatedUnions.ts, 368, 35)) +>Visitor_54834 : Symbol(Visitor_54834, Decl(correlatedUnions.ts, 361, 2)) + +) { + v[node.type](node); +>v : Symbol(v, Decl(correlatedUnions.ts, 368, 35)) +>node.type : Symbol(type, Decl(correlatedUnions.ts, 360, 66), Decl(correlatedUnions.ts, 336, 16), Decl(correlatedUnions.ts, 360, 66), Decl(correlatedUnions.ts, 340, 16), Decl(correlatedUnions.ts, 360, 66) ... and 3 more) +>node : Symbol(node, Decl(correlatedUnions.ts, 367, 56)) +>type : Symbol(type, Decl(correlatedUnions.ts, 360, 66), Decl(correlatedUnions.ts, 336, 16), Decl(correlatedUnions.ts, 360, 66), Decl(correlatedUnions.ts, 340, 16), Decl(correlatedUnions.ts, 360, 66) ... and 3 more) +>node : Symbol(node, Decl(correlatedUnions.ts, 367, 56)) +} + diff --git a/tests/baselines/reference/correlatedUnions.types b/tests/baselines/reference/correlatedUnions.types index 8d328d6c66f79..eae43b70f8c44 100644 --- a/tests/baselines/reference/correlatedUnions.types +++ b/tests/baselines/reference/correlatedUnions.types @@ -900,3 +900,202 @@ function getValueConcrete( >k : K } +// repro from https://github.com/microsoft/TypeScript/issues/54680 + +type A_54680 = { +>A_54680 : { type: "A"; value: string; } + + type: "A"; +>type : "A" + + value: string; +>value : string + +}; + +type B_54680 = { +>B_54680 : { type: "B"; value: number; } + + type: "B"; +>type : "B" + + value: number; +>value : number + +}; + +type Message_54680 = A_54680 | B_54680; +>Message_54680 : A_54680 | B_54680 + +function handle_54680_1(callbacks: { +>handle_54680_1 : (callbacks: { [K in M["type"]]: (msg: Extract["value"]) => unknown; }) => void +>callbacks : { [K in M["type"]]: (msg: Extract["value"]) => unknown; } + + [K in M["type"]]: (msg: Extract["value"]) => unknown; +>msg : Extract["value"] +>type : K + +}) { + window.addEventListener("message", (event) => { +>window.addEventListener("message", (event) => { const msg = event.data as M; callbacks[msg.type as keyof typeof callbacks](msg.value); }) : void +>window.addEventListener : { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } & { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } +>window : Window & typeof globalThis +>addEventListener : { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } & { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } +>"message" : "message" +>(event) => { const msg = event.data as M; callbacks[msg.type as keyof typeof callbacks](msg.value); } : (this: Window, event: MessageEvent) => void +>event : MessageEvent + + const msg = event.data as M; +>msg : M +>event.data as M : M +>event.data : any +>event : MessageEvent +>data : any + + callbacks[msg.type as keyof typeof callbacks](msg.value); +>callbacks[msg.type as keyof typeof callbacks](msg.value) : unknown +>callbacks[msg.type as keyof typeof callbacks] : { [K in M["type"]]: (msg: Extract["value"]) => unknown; }[M["type"]] +>callbacks : { [K in M["type"]]: (msg: Extract["value"]) => unknown; } +>msg.type as keyof typeof callbacks : M["type"] +>msg.type : "A" | "B" +>msg : Message_54680 +>type : "A" | "B" +>callbacks : { [K in M["type"]]: (msg: Extract["value"]) => unknown; } +>msg.value : string | number +>msg : Message_54680 +>value : string | number + + }); +} + +function handle_54680_2(callbacks: { +>handle_54680_2 : (callbacks: { [K in M["type"]]: (msg: (M & { type: K; })["value"]) => unknown; }) => void +>callbacks : { [K in M["type"]]: (msg: (M & { type: K; })["value"]) => unknown; } + + [K in M["type"]]: (msg: (M & { type: K })["value"]) => unknown; +>msg : (M & { type: K; })["value"] +>type : K + +}) { + window.addEventListener("message", (event) => { +>window.addEventListener("message", (event) => { const msg = event.data as M; callbacks[msg.type as keyof typeof callbacks](msg.value); }) : void +>window.addEventListener : { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } & { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } +>window : Window & typeof globalThis +>addEventListener : { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } & { (type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | undefined): void; } +>"message" : "message" +>(event) => { const msg = event.data as M; callbacks[msg.type as keyof typeof callbacks](msg.value); } : (this: Window, event: MessageEvent) => void +>event : MessageEvent + + const msg = event.data as M; +>msg : M +>event.data as M : M +>event.data : any +>event : MessageEvent +>data : any + + callbacks[msg.type as keyof typeof callbacks](msg.value); +>callbacks[msg.type as keyof typeof callbacks](msg.value) : unknown +>callbacks[msg.type as keyof typeof callbacks] : { [K in M["type"]]: (msg: (M & { type: K; })["value"]) => unknown; }[M["type"]] +>callbacks : { [K in M["type"]]: (msg: (M & { type: K; })["value"]) => unknown; } +>msg.type as keyof typeof callbacks : M["type"] +>msg.type : "A" | "B" +>msg : Message_54680 +>type : "A" | "B" +>callbacks : { [K in M["type"]]: (msg: (M & { type: K; })["value"]) => unknown; } +>msg.value : string | number +>msg : Message_54680 +>value : string | number + + }); +} + +// repro from https://github.com/microsoft/TypeScript/issues/54834 + +type NumericLiteral_54834 = { +>NumericLiteral_54834 : { value: number; type: "NumericLiteral"; } + + value: number; +>value : number + + type: "NumericLiteral"; +>type : "NumericLiteral" + +}; +type StringLiteral_54834 = { +>StringLiteral_54834 : { value: string; type: "StringLiteral"; } + + value: string; +>value : string + + type: "StringLiteral"; +>type : "StringLiteral" + +}; +type Identifier_54834 = { +>Identifier_54834 : { name: string; type: "Identifier"; } + + name: string; +>name : string + + type: "Identifier"; +>type : "Identifier" + +}; +type CallExpression_54834 = { +>CallExpression_54834 : { name: string; arguments: DropbearNode_54834[]; type: "CallExpression"; } + + name: string; +>name : string + + arguments: DropbearNode_54834[]; +>arguments : DropbearNode_54834[] + + type: "CallExpression"; +>type : "CallExpression" + +}; + +type DropbearNode_54834 = +>DropbearNode_54834 : NumericLiteral_54834 | StringLiteral_54834 | Identifier_54834 | CallExpression_54834 + + | NumericLiteral_54834 + | StringLiteral_54834 + | Identifier_54834 + | CallExpression_54834; + +type TypeMap_54834 = { +>TypeMap_54834 : { NumericLiteral: NumericLiteral_54834; StringLiteral: StringLiteral_54834; Identifier: Identifier_54834; CallExpression: CallExpression_54834; } + + [K in DropbearNode_54834["type"]]: Extract; +>type : K + +}; + +type Visitor_54834 = { +>Visitor_54834 : { NumericLiteral: (node: Readonly) => void; StringLiteral: (node: Readonly) => void; Identifier: (node: Readonly) => void; CallExpression: (node: Readonly) => void; } + + [K in keyof TypeMap_54834]: (node: Readonly) => void; +>node : Readonly + +}; + +function visitNode_54834( +>visitNode_54834 : (node: Readonly, v: Visitor_54834) => void + + node: Readonly, +>node : Readonly + + v: Visitor_54834 +>v : Visitor_54834 + +) { + v[node.type](node); +>v[node.type](node) : void +>v[node.type] : Visitor_54834[TypeMap_54834[K]["type"]] +>v : Visitor_54834 +>node.type : TypeMap_54834[K]["type"] +>node : Readonly +>type : TypeMap_54834[K]["type"] +>node : Readonly +} + diff --git a/tests/cases/compiler/correlatedUnions.ts b/tests/cases/compiler/correlatedUnions.ts index 460ddf408a104..91c50b9ddf02f 100644 --- a/tests/cases/compiler/correlatedUnions.ts +++ b/tests/cases/compiler/correlatedUnions.ts @@ -301,3 +301,76 @@ function getValueConcrete( ): Foo1[K] | undefined { return o[k]; } + +// repro from https://github.com/microsoft/TypeScript/issues/54680 + +type A_54680 = { + type: "A"; + value: string; +}; + +type B_54680 = { + type: "B"; + value: number; +}; + +type Message_54680 = A_54680 | B_54680; + +function handle_54680_1(callbacks: { + [K in M["type"]]: (msg: Extract["value"]) => unknown; +}) { + window.addEventListener("message", (event) => { + const msg = event.data as M; + callbacks[msg.type as keyof typeof callbacks](msg.value); + }); +} + +function handle_54680_2(callbacks: { + [K in M["type"]]: (msg: (M & { type: K })["value"]) => unknown; +}) { + window.addEventListener("message", (event) => { + const msg = event.data as M; + callbacks[msg.type as keyof typeof callbacks](msg.value); + }); +} + +// repro from https://github.com/microsoft/TypeScript/issues/54834 + +type NumericLiteral_54834 = { + value: number; + type: "NumericLiteral"; +}; +type StringLiteral_54834 = { + value: string; + type: "StringLiteral"; +}; +type Identifier_54834 = { + name: string; + type: "Identifier"; +}; +type CallExpression_54834 = { + name: string; + arguments: DropbearNode_54834[]; + type: "CallExpression"; +}; + +type DropbearNode_54834 = + | NumericLiteral_54834 + | StringLiteral_54834 + | Identifier_54834 + | CallExpression_54834; + +type TypeMap_54834 = { + [K in DropbearNode_54834["type"]]: Extract; +}; + +type Visitor_54834 = { + [K in keyof TypeMap_54834]: (node: Readonly) => void; +}; + +function visitNode_54834( + node: Readonly, + v: Visitor_54834 +) { + v[node.type](node); +}