diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dfd479127202c..68d8658fbb2aa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19839,7 +19839,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeParamMapper = combineTypeMappers((newType as ConditionalType).mapper, newMapper); const typeArguments = map(newRoot.outerTypeParameters, t => getMappedType(t, typeParamMapper)); const newRootMapper = createTypeMapper(newRoot.outerTypeParameters, typeArguments); - const newCheckType = newRoot.isDistributive ? getMappedType(newRoot.checkType, newRootMapper) : undefined; + let newCheckType = newRoot.isDistributive ? getMappedType(newRoot.checkType, newRootMapper) : undefined; + if (newCheckType && isNoInferType(newCheckType)) { + newCheckType = (newCheckType as SubstitutionType).baseType; + } if (!newCheckType || newCheckType === newRoot.checkType || !(newCheckType.flags & (TypeFlags.Union | TypeFlags.Never))) { root = newRoot; mapper = newRootMapper; @@ -20935,7 +20938,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!result) { const newMapper = createTypeMapper(root.outerTypeParameters, typeArguments); const checkType = root.checkType; - const distributionType = root.isDistributive ? getReducedType(getMappedType(checkType, newMapper)) : undefined; + let distributionType = root.isDistributive ? getReducedType(getMappedType(checkType, newMapper)) : undefined; + if (distributionType && isNoInferType(distributionType)) { + distributionType = (distributionType as SubstitutionType).baseType; + } // Distributive conditional types are distributed over union types. For example, when the // distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the // result is (A extends U ? X : Y) | (B extends U ? X : Y). diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType1.symbols b/tests/baselines/reference/noInferVsDistributiveConditionalType1.symbols new file mode 100644 index 0000000000000..2d73830cc67db --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType1.symbols @@ -0,0 +1,128 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType1.ts] //// + +=== noInferVsDistributiveConditionalType1.ts === +// https://github.com/microsoft/TypeScript/issues/61076 + +type FooEvent = { type: "FOO" }; +>FooEvent : Symbol(FooEvent, Decl(noInferVsDistributiveConditionalType1.ts, 0, 0)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType1.ts, 2, 17)) + +type BarEvent = { type: "BAR" }; +>BarEvent : Symbol(BarEvent, Decl(noInferVsDistributiveConditionalType1.ts, 2, 32)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType1.ts, 3, 17)) + +type Input = FooEvent | BarEvent; +>Input : Symbol(Input, Decl(noInferVsDistributiveConditionalType1.ts, 3, 32)) +>FooEvent : Symbol(FooEvent, Decl(noInferVsDistributiveConditionalType1.ts, 0, 0)) +>BarEvent : Symbol(BarEvent, Decl(noInferVsDistributiveConditionalType1.ts, 2, 32)) + +type Result = Extract, FooEvent>; +>Result : Symbol(Result, Decl(noInferVsDistributiveConditionalType1.ts, 5, 33)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>Input : Symbol(Input, Decl(noInferVsDistributiveConditionalType1.ts, 3, 32)) +>FooEvent : Symbol(FooEvent, Decl(noInferVsDistributiveConditionalType1.ts, 0, 0)) + +type EventObject = { +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType1.ts, 6, 48)) + + type: string; +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType1.ts, 8, 20)) + +}; + +type ActionFunction< +>ActionFunction : Symbol(ActionFunction, Decl(noInferVsDistributiveConditionalType1.ts, 10, 2)) + + TExpressionEvent extends EventObject, +>TExpressionEvent : Symbol(TExpressionEvent, Decl(noInferVsDistributiveConditionalType1.ts, 12, 20)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType1.ts, 6, 48)) + + TEvent extends EventObject, +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 13, 39)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType1.ts, 6, 48)) + +> = { + (args: { event: TExpressionEvent }): void; +>args : Symbol(args, Decl(noInferVsDistributiveConditionalType1.ts, 16, 3)) +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType1.ts, 16, 10)) +>TExpressionEvent : Symbol(TExpressionEvent, Decl(noInferVsDistributiveConditionalType1.ts, 12, 20)) + + _out_TEvent?: TEvent; +>_out_TEvent : Symbol(_out_TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 16, 44)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 13, 39)) + +}; + +type TransitionsConfig = { +>TransitionsConfig : Symbol(TransitionsConfig, Decl(noInferVsDistributiveConditionalType1.ts, 18, 2)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 20, 23)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType1.ts, 6, 48)) + + [K in TEvent["type"]]?: { +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType1.ts, 21, 3)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 20, 23)) + + actions?: ActionFunction, TEvent>; +>actions : Symbol(actions, Decl(noInferVsDistributiveConditionalType1.ts, 21, 27)) +>ActionFunction : Symbol(ActionFunction, Decl(noInferVsDistributiveConditionalType1.ts, 10, 2)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 20, 23)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType1.ts, 22, 46)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType1.ts, 21, 3)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 20, 23)) + + }; +}; + +declare function createMachine(config: { +>createMachine : Symbol(createMachine, Decl(noInferVsDistributiveConditionalType1.ts, 24, 2)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 26, 31)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType1.ts, 6, 48)) +>config : Symbol(config, Decl(noInferVsDistributiveConditionalType1.ts, 26, 59)) + + types?: { +>types : Symbol(types, Decl(noInferVsDistributiveConditionalType1.ts, 26, 68)) + + events?: TEvent; +>events : Symbol(events, Decl(noInferVsDistributiveConditionalType1.ts, 27, 11)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 26, 31)) + + }; + on?: TransitionsConfig>; +>on : Symbol(on, Decl(noInferVsDistributiveConditionalType1.ts, 29, 4)) +>TransitionsConfig : Symbol(TransitionsConfig, Decl(noInferVsDistributiveConditionalType1.ts, 18, 2)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType1.ts, 26, 31)) + +}): void; + +createMachine({ +>createMachine : Symbol(createMachine, Decl(noInferVsDistributiveConditionalType1.ts, 24, 2)) + + types: { +>types : Symbol(types, Decl(noInferVsDistributiveConditionalType1.ts, 33, 15)) + + events: {} as Input, +>events : Symbol(events, Decl(noInferVsDistributiveConditionalType1.ts, 34, 10)) +>Input : Symbol(Input, Decl(noInferVsDistributiveConditionalType1.ts, 3, 32)) + + }, + on: { +>on : Symbol(on, Decl(noInferVsDistributiveConditionalType1.ts, 36, 4)) + + FOO: { +>FOO : Symbol(FOO, Decl(noInferVsDistributiveConditionalType1.ts, 37, 7)) + + actions: ({ event }) => { +>actions : Symbol(actions, Decl(noInferVsDistributiveConditionalType1.ts, 38, 10)) +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType1.ts, 39, 17)) + + event; // { type: "FOO"; } +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType1.ts, 39, 17)) + + }, + }, + }, +}); + diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType1.types b/tests/baselines/reference/noInferVsDistributiveConditionalType1.types new file mode 100644 index 0000000000000..bf448a5660dfc --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType1.types @@ -0,0 +1,141 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType1.ts] //// + +=== noInferVsDistributiveConditionalType1.ts === +// https://github.com/microsoft/TypeScript/issues/61076 + +type FooEvent = { type: "FOO" }; +>FooEvent : FooEvent +> : ^^^^^^^^ +>type : "FOO" +> : ^^^^^ + +type BarEvent = { type: "BAR" }; +>BarEvent : BarEvent +> : ^^^^^^^^ +>type : "BAR" +> : ^^^^^ + +type Input = FooEvent | BarEvent; +>Input : Input +> : ^^^^^ + +type Result = Extract, FooEvent>; +>Result : FooEvent +> : ^^^^^^^^ + +type EventObject = { +>EventObject : EventObject +> : ^^^^^^^^^^^ + + type: string; +>type : string +> : ^^^^^^ + +}; + +type ActionFunction< +>ActionFunction : ActionFunction +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TExpressionEvent extends EventObject, + TEvent extends EventObject, +> = { + (args: { event: TExpressionEvent }): void; +>args : { event: TExpressionEvent; } +> : ^^^^^^^^^ ^^^ +>event : TExpressionEvent +> : ^^^^^^^^^^^^^^^^ + + _out_TEvent?: TEvent; +>_out_TEvent : TEvent | undefined +> : ^^^^^^^^^^^^^^^^^^ + +}; + +type TransitionsConfig = { +>TransitionsConfig : TransitionsConfig +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + + [K in TEvent["type"]]?: { + actions?: ActionFunction, TEvent>; +>actions : ActionFunction, TEvent> | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ +>type : K +> : ^ + + }; +}; + +declare function createMachine(config: { +>createMachine : (config: { types?: { events?: TEvent; }; on?: TransitionsConfig>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>config : { types?: { events?: TEvent; }; on?: TransitionsConfig>; } +> : ^^^^^^^^^^ ^^^^^^^ ^^^ + + types?: { +>types : { events?: TEvent; } | undefined +> : ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + + events?: TEvent; +>events : TEvent | undefined +> : ^^^^^^^^^^^^^^^^^^ + + }; + on?: TransitionsConfig>; +>on : TransitionsConfig> | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}): void; + +createMachine({ +>createMachine({ types: { events: {} as Input, }, on: { FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, },}) : void +> : ^^^^ +>createMachine : (config: { types?: { events?: TEvent; }; on?: TransitionsConfig>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>{ types: { events: {} as Input, }, on: { FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, },} : { types: { events: Input; }; on: { FOO: { actions: ({ event }: { event: FooEvent; }) => void; }; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + types: { +>types : { events: Input; } +> : ^^^^^^^^^^ ^^^ +>{ events: {} as Input, } : { events: Input; } +> : ^^^^^^^^^^ ^^^ + + events: {} as Input, +>events : Input +> : ^^^^^ +>{} as Input : Input +> : ^^^^^ +>{} : {} +> : ^^ + + }, + on: { +>on : { FOO: { actions: ({ event }: { event: FooEvent; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, } : { FOO: { actions: ({ event }: { event: FooEvent; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + FOO: { +>FOO : { actions: ({ event }: { event: FooEvent; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ actions: ({ event }) => { event; // { type: "FOO"; } }, } : { actions: ({ event }: { event: FooEvent; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + actions: ({ event }) => { +>actions : ({ event }: { event: FooEvent; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>({ event }) => { event; // { type: "FOO"; } } : ({ event }: { event: FooEvent; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>event : FooEvent +> : ^^^^^^^^ + + event; // { type: "FOO"; } +>event : FooEvent +> : ^^^^^^^^ + + }, + }, + }, +}); + diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType2.symbols b/tests/baselines/reference/noInferVsDistributiveConditionalType2.symbols new file mode 100644 index 0000000000000..2f1b8818ef7e0 --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType2.symbols @@ -0,0 +1,289 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType2.ts] //// + +=== noInferVsDistributiveConditionalType2.ts === +type EventObject = { +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + type: string; +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 0, 20)) + +}; + +type FooEvent = { type: "FOO" }; +>FooEvent : Symbol(FooEvent, Decl(noInferVsDistributiveConditionalType2.ts, 2, 2)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 4, 17)) + +type BarEvent = { type: "BAR" }; +>BarEvent : Symbol(BarEvent, Decl(noInferVsDistributiveConditionalType2.ts, 4, 32)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 5, 17)) + +type Input = FooEvent | BarEvent; +>Input : Symbol(Input, Decl(noInferVsDistributiveConditionalType2.ts, 5, 32)) +>FooEvent : Symbol(FooEvent, Decl(noInferVsDistributiveConditionalType2.ts, 2, 2)) +>BarEvent : Symbol(BarEvent, Decl(noInferVsDistributiveConditionalType2.ts, 4, 32)) + +type ExtractEventSimplified< +>ExtractEventSimplified : Symbol(ExtractEventSimplified, Decl(noInferVsDistributiveConditionalType2.ts, 7, 33)) + + TEvent extends EventObject, +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 9, 28)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + K extends TEvent["type"], +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType2.ts, 10, 29)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 9, 28)) + +> = string extends TEvent["type"] ? TEvent : Extract; +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 9, 28)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 9, 28)) +>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 9, 28)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 12, 62)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType2.ts, 10, 29)) + +type Result = ExtractEventSimplified, "FOO">; +>Result : Symbol(Result, Decl(noInferVsDistributiveConditionalType2.ts, 12, 74)) +>ExtractEventSimplified : Symbol(ExtractEventSimplified, Decl(noInferVsDistributiveConditionalType2.ts, 7, 33)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>Input : Symbol(Input, Decl(noInferVsDistributiveConditionalType2.ts, 5, 32)) + +type EventDescriptorMatches< +>EventDescriptorMatches : Symbol(EventDescriptorMatches, Decl(noInferVsDistributiveConditionalType2.ts, 14, 60)) + + TEventType extends string, +>TEventType : Symbol(TEventType, Decl(noInferVsDistributiveConditionalType2.ts, 16, 28)) + + TNormalizedDescriptor, +>TNormalizedDescriptor : Symbol(TNormalizedDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 17, 28)) + +> = TEventType extends TNormalizedDescriptor ? true : false; +>TEventType : Symbol(TEventType, Decl(noInferVsDistributiveConditionalType2.ts, 16, 28)) +>TNormalizedDescriptor : Symbol(TNormalizedDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 17, 28)) + +type PartialEventDescriptor = +>PartialEventDescriptor : Symbol(PartialEventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 19, 60)) +>TEventType : Symbol(TEventType, Decl(noInferVsDistributiveConditionalType2.ts, 21, 28)) + + TEventType extends `${infer TLeading}.${infer TTail}` +>TEventType : Symbol(TEventType, Decl(noInferVsDistributiveConditionalType2.ts, 21, 28)) +>TLeading : Symbol(TLeading, Decl(noInferVsDistributiveConditionalType2.ts, 22, 29)) +>TTail : Symbol(TTail, Decl(noInferVsDistributiveConditionalType2.ts, 22, 47)) + + ? `${TLeading}.*` | `${TLeading}.${PartialEventDescriptor}` +>TLeading : Symbol(TLeading, Decl(noInferVsDistributiveConditionalType2.ts, 22, 29)) +>TLeading : Symbol(TLeading, Decl(noInferVsDistributiveConditionalType2.ts, 22, 29)) +>PartialEventDescriptor : Symbol(PartialEventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 19, 60)) +>TTail : Symbol(TTail, Decl(noInferVsDistributiveConditionalType2.ts, 22, 47)) + + : never; + +type EventDescriptor = +>EventDescriptor : Symbol(EventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 24, 12)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 26, 21)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + | TEvent["type"] +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 26, 21)) + + | PartialEventDescriptor +>PartialEventDescriptor : Symbol(PartialEventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 19, 60)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 26, 21)) + + | "*"; + +type NormalizeDescriptor = TDescriptor extends "*" +>NormalizeDescriptor : Symbol(NormalizeDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 29, 8)) +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 31, 25)) +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 31, 25)) + + ? string + : TDescriptor extends `${infer TLeading}.*` +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 31, 25)) +>TLeading : Symbol(TLeading, Decl(noInferVsDistributiveConditionalType2.ts, 33, 32)) + + ? `${TLeading}.${string}` +>TLeading : Symbol(TLeading, Decl(noInferVsDistributiveConditionalType2.ts, 33, 32)) + + : TDescriptor; +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 31, 25)) + +type ExtractEvent< +>ExtractEvent : Symbol(ExtractEvent, Decl(noInferVsDistributiveConditionalType2.ts, 35, 16)) + + TEvent extends EventObject, +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + TDescriptor extends EventDescriptor, +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 38, 29)) +>EventDescriptor : Symbol(EventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 24, 12)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) + +> = string extends TEvent["type"] +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) + + ? TEvent +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) + + : NormalizeDescriptor extends infer TNormalizedDescriptor +>NormalizeDescriptor : Symbol(NormalizeDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 29, 8)) +>TDescriptor : Symbol(TDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 38, 29)) +>TNormalizedDescriptor : Symbol(TNormalizedDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 42, 50)) + + ? TEvent extends any +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) + + ? // true is the check type here to match both true and boolean + true extends EventDescriptorMatches +>EventDescriptorMatches : Symbol(EventDescriptorMatches, Decl(noInferVsDistributiveConditionalType2.ts, 14, 60)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) +>TNormalizedDescriptor : Symbol(TNormalizedDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 42, 50)) + + ? TEvent +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 37, 18)) + + : never + : never + : never; + +type ActionFunction< +>ActionFunction : Symbol(ActionFunction, Decl(noInferVsDistributiveConditionalType2.ts, 49, 10)) + + TExpressionEvent extends EventObject, +>TExpressionEvent : Symbol(TExpressionEvent, Decl(noInferVsDistributiveConditionalType2.ts, 51, 20)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + TEvent extends EventObject, +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 52, 39)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + +> = { + (args: { event: TExpressionEvent }): void; +>args : Symbol(args, Decl(noInferVsDistributiveConditionalType2.ts, 55, 3)) +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType2.ts, 55, 10)) +>TExpressionEvent : Symbol(TExpressionEvent, Decl(noInferVsDistributiveConditionalType2.ts, 51, 20)) + + _out_TEvent?: TEvent; +>_out_TEvent : Symbol(_out_TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 55, 44)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 52, 39)) + +}; + +type TransitionsConfig = { +>TransitionsConfig : Symbol(TransitionsConfig, Decl(noInferVsDistributiveConditionalType2.ts, 57, 2)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 59, 23)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) + + [K in EventDescriptor]?: { +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType2.ts, 60, 3)) +>EventDescriptor : Symbol(EventDescriptor, Decl(noInferVsDistributiveConditionalType2.ts, 24, 12)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 59, 23)) + + actions?: ActionFunction, TEvent>; +>actions : Symbol(actions, Decl(noInferVsDistributiveConditionalType2.ts, 60, 36)) +>ActionFunction : Symbol(ActionFunction, Decl(noInferVsDistributiveConditionalType2.ts, 49, 10)) +>ExtractEvent : Symbol(ExtractEvent, Decl(noInferVsDistributiveConditionalType2.ts, 35, 16)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 59, 23)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType2.ts, 60, 3)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 59, 23)) + + }; +}; + +declare function createMachine(config: { +>createMachine : Symbol(createMachine, Decl(noInferVsDistributiveConditionalType2.ts, 63, 2)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 65, 31)) +>EventObject : Symbol(EventObject, Decl(noInferVsDistributiveConditionalType2.ts, 0, 0)) +>config : Symbol(config, Decl(noInferVsDistributiveConditionalType2.ts, 65, 59)) + + types?: { +>types : Symbol(types, Decl(noInferVsDistributiveConditionalType2.ts, 65, 68)) + + events?: TEvent; +>events : Symbol(events, Decl(noInferVsDistributiveConditionalType2.ts, 66, 11)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 65, 31)) + + }; + on?: TransitionsConfig>; +>on : Symbol(on, Decl(noInferVsDistributiveConditionalType2.ts, 68, 4)) +>TransitionsConfig : Symbol(TransitionsConfig, Decl(noInferVsDistributiveConditionalType2.ts, 57, 2)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>TEvent : Symbol(TEvent, Decl(noInferVsDistributiveConditionalType2.ts, 65, 31)) + +}): void; + +createMachine({ +>createMachine : Symbol(createMachine, Decl(noInferVsDistributiveConditionalType2.ts, 63, 2)) + + types: { +>types : Symbol(types, Decl(noInferVsDistributiveConditionalType2.ts, 72, 15)) + + events: {} as { type: "FOO" } | { type: "BAR" }, +>events : Symbol(events, Decl(noInferVsDistributiveConditionalType2.ts, 73, 10)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 74, 19)) +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 74, 37)) + + }, + on: { +>on : Symbol(on, Decl(noInferVsDistributiveConditionalType2.ts, 75, 4)) + + FOO: { +>FOO : Symbol(FOO, Decl(noInferVsDistributiveConditionalType2.ts, 76, 7)) + + actions: ({ event }) => { +>actions : Symbol(actions, Decl(noInferVsDistributiveConditionalType2.ts, 77, 10)) +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType2.ts, 78, 17)) + + event; // { type: "FOO"; } +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType2.ts, 78, 17)) + + }, + }, + }, +}); + +createMachine({ +>createMachine : Symbol(createMachine, Decl(noInferVsDistributiveConditionalType2.ts, 63, 2)) + + types: {} as { +>types : Symbol(types, Decl(noInferVsDistributiveConditionalType2.ts, 85, 15)) + + events: +>events : Symbol(events, Decl(noInferVsDistributiveConditionalType2.ts, 86, 16)) + + | { type: "mouse.click.up"; direction: "up" } +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 88, 9)) +>direction : Symbol(direction, Decl(noInferVsDistributiveConditionalType2.ts, 88, 33)) + + | { type: "mouse.click.down"; direction: "down" } +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 89, 9)) +>direction : Symbol(direction, Decl(noInferVsDistributiveConditionalType2.ts, 89, 35)) + + | { type: "mouse.move" } +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 90, 9)) + + | { type: "mouse" } +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 91, 9)) + + | { type: "keypress" }; +>type : Symbol(type, Decl(noInferVsDistributiveConditionalType2.ts, 92, 9)) + + }, + on: { +>on : Symbol(on, Decl(noInferVsDistributiveConditionalType2.ts, 93, 4)) + + "mouse.*": { +>"mouse.*" : Symbol("mouse.*", Decl(noInferVsDistributiveConditionalType2.ts, 94, 7)) + + actions: ({ event }) => { +>actions : Symbol(actions, Decl(noInferVsDistributiveConditionalType2.ts, 95, 16)) +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType2.ts, 96, 17)) + + event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } +>event : Symbol(event, Decl(noInferVsDistributiveConditionalType2.ts, 96, 17)) + + }, + }, + }, +}); + diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType2.types b/tests/baselines/reference/noInferVsDistributiveConditionalType2.types new file mode 100644 index 0000000000000..57ee7de52fba9 --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType2.types @@ -0,0 +1,282 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType2.ts] //// + +=== noInferVsDistributiveConditionalType2.ts === +type EventObject = { +>EventObject : EventObject +> : ^^^^^^^^^^^ + + type: string; +>type : string +> : ^^^^^^ + +}; + +type FooEvent = { type: "FOO" }; +>FooEvent : FooEvent +> : ^^^^^^^^ +>type : "FOO" +> : ^^^^^ + +type BarEvent = { type: "BAR" }; +>BarEvent : BarEvent +> : ^^^^^^^^ +>type : "BAR" +> : ^^^^^ + +type Input = FooEvent | BarEvent; +>Input : Input +> : ^^^^^ + +type ExtractEventSimplified< +>ExtractEventSimplified : ExtractEventSimplified +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TEvent extends EventObject, + K extends TEvent["type"], +> = string extends TEvent["type"] ? TEvent : Extract; +>type : K +> : ^ + +type Result = ExtractEventSimplified, "FOO">; +>Result : FooEvent +> : ^^^^^^^^ + +type EventDescriptorMatches< +>EventDescriptorMatches : EventDescriptorMatches +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TEventType extends string, + TNormalizedDescriptor, +> = TEventType extends TNormalizedDescriptor ? true : false; +>true : true +> : ^^^^ +>false : false +> : ^^^^^ + +type PartialEventDescriptor = +>PartialEventDescriptor : PartialEventDescriptor +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TEventType extends `${infer TLeading}.${infer TTail}` + ? `${TLeading}.*` | `${TLeading}.${PartialEventDescriptor}` + : never; + +type EventDescriptor = +>EventDescriptor : EventDescriptor +> : ^^^^^^^^^^^^^^^^^^^^^^^ + + | TEvent["type"] + | PartialEventDescriptor + | "*"; + +type NormalizeDescriptor = TDescriptor extends "*" +>NormalizeDescriptor : NormalizeDescriptor +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ? string + : TDescriptor extends `${infer TLeading}.*` + ? `${TLeading}.${string}` + : TDescriptor; + +type ExtractEvent< +>ExtractEvent : ExtractEvent +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TEvent extends EventObject, + TDescriptor extends EventDescriptor, +> = string extends TEvent["type"] + ? TEvent + : NormalizeDescriptor extends infer TNormalizedDescriptor + ? TEvent extends any + ? // true is the check type here to match both true and boolean + true extends EventDescriptorMatches +>true : true +> : ^^^^ + + ? TEvent + : never + : never + : never; + +type ActionFunction< +>ActionFunction : ActionFunction +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + TExpressionEvent extends EventObject, + TEvent extends EventObject, +> = { + (args: { event: TExpressionEvent }): void; +>args : { event: TExpressionEvent; } +> : ^^^^^^^^^ ^^^ +>event : TExpressionEvent +> : ^^^^^^^^^^^^^^^^ + + _out_TEvent?: TEvent; +>_out_TEvent : TEvent | undefined +> : ^^^^^^^^^^^^^^^^^^ + +}; + +type TransitionsConfig = { +>TransitionsConfig : TransitionsConfig +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + + [K in EventDescriptor]?: { + actions?: ActionFunction, TEvent>; +>actions : ActionFunction, TEvent> | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + }; +}; + +declare function createMachine(config: { +>createMachine : (config: { types?: { events?: TEvent; }; on?: TransitionsConfig>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>config : { types?: { events?: TEvent; }; on?: TransitionsConfig>; } +> : ^^^^^^^^^^ ^^^^^^^ ^^^ + + types?: { +>types : { events?: TEvent; } | undefined +> : ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + + events?: TEvent; +>events : TEvent | undefined +> : ^^^^^^^^^^^^^^^^^^ + + }; + on?: TransitionsConfig>; +>on : TransitionsConfig> | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +}): void; + +createMachine({ +>createMachine({ types: { events: {} as { type: "FOO" } | { type: "BAR" }, }, on: { FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, },}) : void +> : ^^^^ +>createMachine : (config: { types?: { events?: TEvent; }; on?: TransitionsConfig>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>{ types: { events: {} as { type: "FOO" } | { type: "BAR" }, }, on: { FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, },} : { types: { events: { type: "FOO"; } | { type: "BAR"; }; }; on: { FOO: { actions: ({ event }: { event: { type: "FOO"; }; }) => void; }; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ + + types: { +>types : { events: { type: "FOO"; } | { type: "BAR"; }; } +> : ^^^^^^^^^^ ^^^ +>{ events: {} as { type: "FOO" } | { type: "BAR" }, } : { events: { type: "FOO"; } | { type: "BAR"; }; } +> : ^^^^^^^^^^ ^^^ + + events: {} as { type: "FOO" } | { type: "BAR" }, +>events : { type: "FOO"; } | { type: "BAR"; } +> : ^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ +>{} as { type: "FOO" } | { type: "BAR" } : { type: "FOO"; } | { type: "BAR"; } +> : ^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ +>{} : {} +> : ^^ +>type : "FOO" +> : ^^^^^ +>type : "BAR" +> : ^^^^^ + + }, + on: { +>on : { FOO: { actions: ({ event }: { event: { type: "FOO"; }; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ +>{ FOO: { actions: ({ event }) => { event; // { type: "FOO"; } }, }, } : { FOO: { actions: ({ event }: { event: { type: "FOO"; }; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ + + FOO: { +>FOO : { actions: ({ event }: { event: { type: "FOO"; }; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ +>{ actions: ({ event }) => { event; // { type: "FOO"; } }, } : { actions: ({ event }: { event: { type: "FOO"; }; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ + + actions: ({ event }) => { +>actions : ({ event }: { event: { type: "FOO"; }; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ +>({ event }) => { event; // { type: "FOO"; } } : ({ event }: { event: { type: "FOO"; }; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ +>event : { type: "FOO"; } +> : ^^^^^^^^ ^^^ + + event; // { type: "FOO"; } +>event : { type: "FOO"; } +> : ^^^^^^^^ ^^^ + + }, + }, + }, +}); + +createMachine({ +>createMachine({ types: {} as { events: | { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } | { type: "mouse" } | { type: "keypress" }; }, on: { "mouse.*": { actions: ({ event }) => { event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } }, }, },}) : void +> : ^^^^ +>createMachine : (config: { types?: { events?: TEvent; }; on?: TransitionsConfig>; }) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>{ types: {} as { events: | { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } | { type: "mouse" } | { type: "keypress" }; }, on: { "mouse.*": { actions: ({ event }) => { event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } }, }, },} : { types: { events: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } | { type: "mouse"; } | { type: "keypress"; }; }; on: { "mouse.*": { actions: ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void; }; }; } +> : ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ + + types: {} as { +>types : { events: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } | { type: "mouse"; } | { type: "keypress"; }; } +> : ^^^^^^^^^^ ^^^ +>{} as { events: | { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } | { type: "mouse" } | { type: "keypress" }; } : { events: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } | { type: "mouse"; } | { type: "keypress"; }; } +> : ^^^^^^^^^^ ^^^ +>{} : {} +> : ^^ + + events: +>events : { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } | { type: "mouse"; } | { type: "keypress"; } +> : ^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ + + | { type: "mouse.click.up"; direction: "up" } +>type : "mouse.click.up" +> : ^^^^^^^^^^^^^^^^ +>direction : "up" +> : ^^^^ + + | { type: "mouse.click.down"; direction: "down" } +>type : "mouse.click.down" +> : ^^^^^^^^^^^^^^^^^^ +>direction : "down" +> : ^^^^^^ + + | { type: "mouse.move" } +>type : "mouse.move" +> : ^^^^^^^^^^^^ + + | { type: "mouse" } +>type : "mouse" +> : ^^^^^^^ + + | { type: "keypress" }; +>type : "keypress" +> : ^^^^^^^^^^ + + }, + on: { +>on : { "mouse.*": { actions: ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ +>{ "mouse.*": { actions: ({ event }) => { event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } }, }, } : { "mouse.*": { actions: ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ + + "mouse.*": { +>"mouse.*" : { actions: ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ +>{ actions: ({ event }) => { event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } }, } : { actions: ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ + + actions: ({ event }) => { +>actions : ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ +>({ event }) => { event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } } : ({ event }: { event: { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; }; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ +>event : { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } +> : ^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ + + event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } +>event : { type: "mouse.click.up"; direction: "up"; } | { type: "mouse.click.down"; direction: "down"; } | { type: "mouse.move"; } +> : ^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ + + }, + }, + }, +}); + diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType3.symbols b/tests/baselines/reference/noInferVsDistributiveConditionalType3.symbols new file mode 100644 index 0000000000000..289ddd030424c --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType3.symbols @@ -0,0 +1,176 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType3.ts] //// + +=== noInferVsDistributiveConditionalType3.ts === +// based on https://github.com/microsoft/TypeScript/issues/51831 + +type NoMatchAll = Exclude +>NoMatchAll : Symbol(NoMatchAll, Decl(noInferVsDistributiveConditionalType3.ts, 0, 0)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 2, 16)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 2, 16)) + +type Union = { +>Union : Symbol(Union, Decl(noInferVsDistributiveConditionalType3.ts, 2, 36)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 4, 11)) + + [P in keyof T]: ({ [Q in "kind"]: P } & T[P]) extends infer U ? { [Q in keyof U]: U[Q] } : never +>P : Symbol(P, Decl(noInferVsDistributiveConditionalType3.ts, 5, 3)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 4, 11)) +>Q : Symbol(Q, Decl(noInferVsDistributiveConditionalType3.ts, 5, 22)) +>P : Symbol(P, Decl(noInferVsDistributiveConditionalType3.ts, 5, 3)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 4, 11)) +>P : Symbol(P, Decl(noInferVsDistributiveConditionalType3.ts, 5, 3)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 5, 61)) +>Q : Symbol(Q, Decl(noInferVsDistributiveConditionalType3.ts, 5, 69)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 5, 61)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 5, 61)) +>Q : Symbol(Q, Decl(noInferVsDistributiveConditionalType3.ts, 5, 69)) + +}[keyof T] +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 4, 11)) + +type UnionMap = { [K in U["kind"]]: U extends { kind: K } ? U : never } +>UnionMap : Symbol(UnionMap, Decl(noInferVsDistributiveConditionalType3.ts, 6, 10)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 7, 14)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 7, 25)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 7, 47)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 7, 14)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 7, 14)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 7, 75)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 7, 47)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 7, 14)) + +type ExhaustivePattern = { [K in T["kind"] as NoMatchAll]: (u1: UnionMap[K]) => R }; +>ExhaustivePattern : Symbol(ExhaustivePattern, Decl(noInferVsDistributiveConditionalType3.ts, 7, 99)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 8, 23)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 8, 34)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 8, 50)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 8, 59)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 8, 23)) +>NoMatchAll : Symbol(NoMatchAll, Decl(noInferVsDistributiveConditionalType3.ts, 0, 0)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 8, 59)) +>u1 : Symbol(u1, Decl(noInferVsDistributiveConditionalType3.ts, 8, 94)) +>UnionMap : Symbol(UnionMap, Decl(noInferVsDistributiveConditionalType3.ts, 6, 10)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 8, 23)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 8, 59)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 8, 50)) + +type NonExhaustivePattern = { [K in T["kind"] as NoMatchAll]?: (u2: UnionMap[K]) => R } & {_: (union: T) => R}; +>NonExhaustivePattern : Symbol(NonExhaustivePattern, Decl(noInferVsDistributiveConditionalType3.ts, 8, 121)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 9, 26)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 9, 37)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 9, 53)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 9, 62)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 9, 26)) +>NoMatchAll : Symbol(NoMatchAll, Decl(noInferVsDistributiveConditionalType3.ts, 0, 0)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 9, 62)) +>u2 : Symbol(u2, Decl(noInferVsDistributiveConditionalType3.ts, 9, 98)) +>UnionMap : Symbol(UnionMap, Decl(noInferVsDistributiveConditionalType3.ts, 6, 10)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 9, 26)) +>K : Symbol(K, Decl(noInferVsDistributiveConditionalType3.ts, 9, 62)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 9, 53)) +>_ : Symbol(_, Decl(noInferVsDistributiveConditionalType3.ts, 9, 128)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 9, 132)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 9, 26)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 9, 53)) + +type Pattern = ExhaustivePattern | NonExhaustivePattern; +>Pattern : Symbol(Pattern, Decl(noInferVsDistributiveConditionalType3.ts, 9, 148)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 10, 13)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 10, 24)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 10, 40)) +>ExhaustivePattern : Symbol(ExhaustivePattern, Decl(noInferVsDistributiveConditionalType3.ts, 7, 99)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 10, 13)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 10, 40)) +>NonExhaustivePattern : Symbol(NonExhaustivePattern, Decl(noInferVsDistributiveConditionalType3.ts, 8, 121)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 10, 13)) +>R : Symbol(R, Decl(noInferVsDistributiveConditionalType3.ts, 10, 40)) + +function match(union: U, pattern: Pattern, T>): T { +>match : Symbol(match, Decl(noInferVsDistributiveConditionalType3.ts, 10, 99)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 12, 15)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 12, 26)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 12, 42)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 12, 46)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 12, 15)) +>pattern : Symbol(pattern, Decl(noInferVsDistributiveConditionalType3.ts, 12, 55)) +>Pattern : Symbol(Pattern, Decl(noInferVsDistributiveConditionalType3.ts, 9, 148)) +>NoInfer : Symbol(NoInfer, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 12, 15)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 12, 42)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 12, 42)) + + if((pattern as any)[union.kind]) { +>pattern : Symbol(pattern, Decl(noInferVsDistributiveConditionalType3.ts, 12, 55)) +>union.kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 12, 26)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 12, 46)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 12, 26)) + + return (pattern as any)[union.kind](union as U) as T +>pattern : Symbol(pattern, Decl(noInferVsDistributiveConditionalType3.ts, 12, 55)) +>union.kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 12, 26)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 12, 46)) +>kind : Symbol(kind, Decl(noInferVsDistributiveConditionalType3.ts, 12, 26)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 12, 46)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 12, 15)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 12, 42)) + } + return (pattern as any)["_"](union as U) as T +>pattern : Symbol(pattern, Decl(noInferVsDistributiveConditionalType3.ts, 12, 55)) +>union : Symbol(union, Decl(noInferVsDistributiveConditionalType3.ts, 12, 46)) +>U : Symbol(U, Decl(noInferVsDistributiveConditionalType3.ts, 12, 15)) +>T : Symbol(T, Decl(noInferVsDistributiveConditionalType3.ts, 12, 42)) +} + +type ValueType = Union<{ +>ValueType : Symbol(ValueType, Decl(noInferVsDistributiveConditionalType3.ts, 17, 1)) +>Union : Symbol(Union, Decl(noInferVsDistributiveConditionalType3.ts, 2, 36)) + + String: {value: string}, +>String : Symbol(String, Decl(noInferVsDistributiveConditionalType3.ts, 19, 24)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 20, 11)) + + Number: {value: number}, +>Number : Symbol(Number, Decl(noInferVsDistributiveConditionalType3.ts, 20, 26)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 21, 11)) + + Boolean: {value: boolean}, +>Boolean : Symbol(Boolean, Decl(noInferVsDistributiveConditionalType3.ts, 21, 26)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 22, 12)) + + Date: {value: Date} +>Date : Symbol(Date, Decl(noInferVsDistributiveConditionalType3.ts, 22, 28)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 23, 9)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +}> + +function main(value: ValueType) { +>main : Symbol(main, Decl(noInferVsDistributiveConditionalType3.ts, 24, 2)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 26, 14)) +>ValueType : Symbol(ValueType, Decl(noInferVsDistributiveConditionalType3.ts, 17, 1)) + + let test1 = match(value, { +>test1 : Symbol(test1, Decl(noInferVsDistributiveConditionalType3.ts, 27, 5)) +>match : Symbol(match, Decl(noInferVsDistributiveConditionalType3.ts, 10, 99)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 26, 14)) + + String: ({value}) => value, +>String : Symbol(String, Decl(noInferVsDistributiveConditionalType3.ts, 27, 28)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 28, 14)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 28, 14)) + + Number: ({value}) => value.toString(), +>Number : Symbol(Number, Decl(noInferVsDistributiveConditionalType3.ts, 28, 31)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 29, 14)) +>value.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) +>value : Symbol(value, Decl(noInferVsDistributiveConditionalType3.ts, 29, 14)) +>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --)) + + _: (token) => "Unknown" +>_ : Symbol(_, Decl(noInferVsDistributiveConditionalType3.ts, 29, 42)) +>token : Symbol(token, Decl(noInferVsDistributiveConditionalType3.ts, 30, 8)) + + }); +} + diff --git a/tests/baselines/reference/noInferVsDistributiveConditionalType3.types b/tests/baselines/reference/noInferVsDistributiveConditionalType3.types new file mode 100644 index 0000000000000..d042137bf2b59 --- /dev/null +++ b/tests/baselines/reference/noInferVsDistributiveConditionalType3.types @@ -0,0 +1,196 @@ +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType3.ts] //// + +=== noInferVsDistributiveConditionalType3.ts === +// based on https://github.com/microsoft/TypeScript/issues/51831 + +type NoMatchAll = Exclude +>NoMatchAll : NoMatchAll +> : ^^^^^^^^^^^^^ + +type Union = { +>Union : Union +> : ^^^^^^^^ + + [P in keyof T]: ({ [Q in "kind"]: P } & T[P]) extends infer U ? { [Q in keyof U]: U[Q] } : never +}[keyof T] +type UnionMap = { [K in U["kind"]]: U extends { kind: K } ? U : never } +>UnionMap : UnionMap +> : ^^^^^^^^^^^ +>kind : string +> : ^^^^^^ +>kind : K +> : ^ + +type ExhaustivePattern = { [K in T["kind"] as NoMatchAll]: (u1: UnionMap[K]) => R }; +>ExhaustivePattern : ExhaustivePattern +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>kind : string +> : ^^^^^^ +>u1 : UnionMap[K] +> : ^^^^^^^^^^^^^^ + +type NonExhaustivePattern = { [K in T["kind"] as NoMatchAll]?: (u2: UnionMap[K]) => R } & {_: (union: T) => R}; +>NonExhaustivePattern : NonExhaustivePattern +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>kind : string +> : ^^^^^^ +>u2 : UnionMap[K] +> : ^^^^^^^^^^^^^^ +>_ : (union: T) => R +> : ^ ^^ ^^^^^ +>union : T +> : ^ + +type Pattern = ExhaustivePattern | NonExhaustivePattern; +>Pattern : Pattern +> : ^^^^^^^^^^^^^ +>kind : string +> : ^^^^^^ + +function match(union: U, pattern: Pattern, T>): T { +>match : (union: U, pattern: Pattern, T>) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>kind : string +> : ^^^^^^ +>union : U +> : ^ +>pattern : Pattern, T> +> : ^^^^^^^^^^^^^^^^^^^^^^ + + if((pattern as any)[union.kind]) { +>(pattern as any)[union.kind] : any +>(pattern as any) : any +>pattern as any : any +>pattern : Pattern, T> +> : ^^^^^^^^^^^^^^^^^^^^^^ +>union.kind : string +> : ^^^^^^ +>union : U +> : ^ +>kind : string +> : ^^^^^^ + + return (pattern as any)[union.kind](union as U) as T +>(pattern as any)[union.kind](union as U) as T : T +> : ^ +>(pattern as any)[union.kind](union as U) : any +>(pattern as any)[union.kind] : any +>(pattern as any) : any +>pattern as any : any +>pattern : Pattern, T> +> : ^^^^^^^^^^^^^^^^^^^^^^ +>union.kind : string +> : ^^^^^^ +>union : U +> : ^ +>kind : string +> : ^^^^^^ +>union as U : U +> : ^ +>union : U +> : ^ + } + return (pattern as any)["_"](union as U) as T +>(pattern as any)["_"](union as U) as T : T +> : ^ +>(pattern as any)["_"](union as U) : any +>(pattern as any)["_"] : any +>(pattern as any) : any +>pattern as any : any +>pattern : Pattern, T> +> : ^^^^^^^^^^^^^^^^^^^^^^ +>"_" : "_" +> : ^^^ +>union as U : U +> : ^ +>union : U +> : ^ +} + +type ValueType = Union<{ +>ValueType : ValueType +> : ^^^^^^^^^ + + String: {value: string}, +>String : { value: string; } +> : ^^^^^^^^^ ^^^ +>value : string +> : ^^^^^^ + + Number: {value: number}, +>Number : { value: number; } +> : ^^^^^^^^^ ^^^ +>value : number +> : ^^^^^^ + + Boolean: {value: boolean}, +>Boolean : { value: boolean; } +> : ^^^^^^^^^ ^^^ +>value : boolean +> : ^^^^^^^ + + Date: {value: Date} +>Date : { value: Date; } +> : ^^^^^^^^^ ^^^ +>value : Date +> : ^^^^ + +}> + +function main(value: ValueType) { +>main : (value: ValueType) => void +> : ^ ^^ ^^^^^^^^^ +>value : ValueType +> : ^^^^^^^^^ + + let test1 = match(value, { +>test1 : string +> : ^^^^^^ +>match(value, { String: ({value}) => value, Number: ({value}) => value.toString(), _: (token) => "Unknown" }) : string +> : ^^^^^^ +>match : (union: U, pattern: Pattern, T>) => T +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>value : ValueType +> : ^^^^^^^^^ +>{ String: ({value}) => value, Number: ({value}) => value.toString(), _: (token) => "Unknown" } : { String: ({ value }: { kind: "String"; value: string; }) => string; Number: ({ value }: { kind: "Number"; value: number; }) => string; _: (token: NoInfer) => string; } +> : ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + String: ({value}) => value, +>String : ({ value }: { kind: "String"; value: string; }) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ +>({value}) => value : ({ value }: { kind: "String"; value: string; }) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ +>value : string +> : ^^^^^^ +>value : string +> : ^^^^^^ + + Number: ({value}) => value.toString(), +>Number : ({ value }: { kind: "Number"; value: number; }) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ +>({value}) => value.toString() : ({ value }: { kind: "Number"; value: number; }) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ +>value : number +> : ^^^^^^ +>value.toString() : string +> : ^^^^^^ +>value.toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ +>value : number +> : ^^^^^^ +>toString : (radix?: number) => string +> : ^ ^^^ ^^^^^ + + _: (token) => "Unknown" +>_ : (token: NoInfer) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(token) => "Unknown" : (token: NoInfer) => string +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>token : NoInfer +> : ^^^^^^^^^^^^^^^^^^ +>"Unknown" : "Unknown" +> : ^^^^^^^^^ + + }); +} + diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType1.ts b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType1.ts new file mode 100644 index 0000000000000..e924e33e2f31f --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType1.ts @@ -0,0 +1,48 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/61076 + +type FooEvent = { type: "FOO" }; +type BarEvent = { type: "BAR" }; + +type Input = FooEvent | BarEvent; +type Result = Extract, FooEvent>; + +type EventObject = { + type: string; +}; + +type ActionFunction< + TExpressionEvent extends EventObject, + TEvent extends EventObject, +> = { + (args: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; +}; + +type TransitionsConfig = { + [K in TEvent["type"]]?: { + actions?: ActionFunction, TEvent>; + }; +}; + +declare function createMachine(config: { + types?: { + events?: TEvent; + }; + on?: TransitionsConfig>; +}): void; + +createMachine({ + types: { + events: {} as Input, + }, + on: { + FOO: { + actions: ({ event }) => { + event; // { type: "FOO"; } + }, + }, + }, +}); diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType2.ts b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType2.ts new file mode 100644 index 0000000000000..b49c8f94c2fd1 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType2.ts @@ -0,0 +1,105 @@ +// @strict: true +// @noEmit: true + +type EventObject = { + type: string; +}; + +type FooEvent = { type: "FOO" }; +type BarEvent = { type: "BAR" }; + +type Input = FooEvent | BarEvent; + +type ExtractEventSimplified< + TEvent extends EventObject, + K extends TEvent["type"], +> = string extends TEvent["type"] ? TEvent : Extract; + +type Result = ExtractEventSimplified, "FOO">; + +type EventDescriptorMatches< + TEventType extends string, + TNormalizedDescriptor, +> = TEventType extends TNormalizedDescriptor ? true : false; + +type PartialEventDescriptor = + TEventType extends `${infer TLeading}.${infer TTail}` + ? `${TLeading}.*` | `${TLeading}.${PartialEventDescriptor}` + : never; + +type EventDescriptor = + | TEvent["type"] + | PartialEventDescriptor + | "*"; + +type NormalizeDescriptor = TDescriptor extends "*" + ? string + : TDescriptor extends `${infer TLeading}.*` + ? `${TLeading}.${string}` + : TDescriptor; + +type ExtractEvent< + TEvent extends EventObject, + TDescriptor extends EventDescriptor, +> = string extends TEvent["type"] + ? TEvent + : NormalizeDescriptor extends infer TNormalizedDescriptor + ? TEvent extends any + ? // true is the check type here to match both true and boolean + true extends EventDescriptorMatches + ? TEvent + : never + : never + : never; + +type ActionFunction< + TExpressionEvent extends EventObject, + TEvent extends EventObject, +> = { + (args: { event: TExpressionEvent }): void; + _out_TEvent?: TEvent; +}; + +type TransitionsConfig = { + [K in EventDescriptor]?: { + actions?: ActionFunction, TEvent>; + }; +}; + +declare function createMachine(config: { + types?: { + events?: TEvent; + }; + on?: TransitionsConfig>; +}): void; + +createMachine({ + types: { + events: {} as { type: "FOO" } | { type: "BAR" }, + }, + on: { + FOO: { + actions: ({ event }) => { + event; // { type: "FOO"; } + }, + }, + }, +}); + +createMachine({ + types: {} as { + events: + | { type: "mouse.click.up"; direction: "up" } + | { type: "mouse.click.down"; direction: "down" } + | { type: "mouse.move" } + | { type: "mouse" } + | { type: "keypress" }; + }, + on: { + "mouse.*": { + actions: ({ event }) => { + event; // { type: "mouse.click.up"; direction: "up" } | { type: "mouse.click.down"; direction: "down" } | { type: "mouse.move" } + }, + }, + }, +}); diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType3.ts b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType3.ts new file mode 100644 index 0000000000000..cff3ed1253e6d --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/noInferVsDistributiveConditionalType3.ts @@ -0,0 +1,36 @@ +// @strict: true +// @noEmit: true + +// based on https://github.com/microsoft/TypeScript/issues/51831 + +type NoMatchAll = Exclude + +type Union = { + [P in keyof T]: ({ [Q in "kind"]: P } & T[P]) extends infer U ? { [Q in keyof U]: U[Q] } : never +}[keyof T] +type UnionMap = { [K in U["kind"]]: U extends { kind: K } ? U : never } +type ExhaustivePattern = { [K in T["kind"] as NoMatchAll]: (u1: UnionMap[K]) => R }; +type NonExhaustivePattern = { [K in T["kind"] as NoMatchAll]?: (u2: UnionMap[K]) => R } & {_: (union: T) => R}; +type Pattern = ExhaustivePattern | NonExhaustivePattern; + +function match(union: U, pattern: Pattern, T>): T { + if((pattern as any)[union.kind]) { + return (pattern as any)[union.kind](union as U) as T + } + return (pattern as any)["_"](union as U) as T +} + +type ValueType = Union<{ + String: {value: string}, + Number: {value: number}, + Boolean: {value: boolean}, + Date: {value: Date} +}> + +function main(value: ValueType) { + let test1 = match(value, { + String: ({value}) => value, + Number: ({value}) => value.toString(), + _: (token) => "Unknown" + }); +}