-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Closed
Labels
DuplicateAn existing issue was already createdAn existing issue was already created
Description
Bug Report
Type has to be explicit defined while being resolved correctly?!
π Version & Regression Information
- This is the behavior in every version I tried
π Search Terms
Type inference, Union, Pattern
β― Playground Link
Playground link with relevant code
π» Code
type Union<T extends object> = {
[P in keyof T]: ({ [Q in "kind"]: P } & T[P]) extends infer U ? { [Q in keyof U]: U[Q] } : never
}[keyof T]
type UnionMap<U extends { kind: string }> = { [K in U["kind"]]: U extends { kind: K } ? U : never }
type ExhaustivePattern<T extends { kind: string }, R> = { [K in T["kind"]]: (union: UnionMap<T>[K]) => R };
type NonExhaustivePattern<T extends { kind: string }, R> = { [K in T["kind"]]?: (union: UnionMap<T>[K]) => R } & {_: (union: T) => R};
type Pattern<T extends { kind: string }, R> = ExhaustivePattern<T, R> | NonExhaustivePattern<T, R>;
function match<U extends { kind: string }, T>(union: U, pattern: Pattern<U, 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}
}>
let value: ValueType = {kind: "String", value: "Hello"};
function main(value: ValueType) {
let test1 = match(value, {
String: ({value}) => value,
Number: ({value}) => value.toString(),
_: (token) => "Unknown"
});
console.log(test1);
let test2 = match<ValueType, string>(value, {
String: ({value}) => value,
Number: ({value}) => value.toString(),
_: ({kind}) => kind
});
console.log(test2);
}π Actual behavior
Typescript throws an type error
π Expected behavior
Type should be correctly inferred without explicitly defining the type
Metadata
Metadata
Assignees
Labels
DuplicateAn existing issue was already createdAn existing issue was already created
