reactjs - Använda generiska som metodargument i diskriminerade unioner
Låt oss säga att vi har en diskriminerad union som accepterar ett argument av sig själv:
type TextInput<Props extends Inputs<Props>> = {
type: 'text',
value?: string,
options?: undefined
}
type CheckboxInput<Props extends Inputs<Props>> = {
type: 'checkbox',
options: string[] | number[],
value?: Props['options'] extends Array<infer T> ? T : never
}
type Events<Props extends Inputs<Props>> = { onInput?: (arg: Inputs<Props>['value']) => any }
type Inputs<Props extends Inputs<Props>> = TextInput<Props> | CheckboxInput<Props>
Detta fungerar, och vi kan göra några ganska anmärkningsvärda saker:
type Make = <P extends Inputs<P>>(props: P) => {}
declare const create: Make
create({ type: 'text', value: '123' }) // 👍
create({ type: 'text', value: 123 }) // 👍 (value must be a string)
^^^^^^^^^^
create({ type: 'checkbox', options: ['a', 'b'], value: 'a' }) // 👍
create({ type: 'checkbox', options: [1, 2, 3], value: 2 }) // 👍
create({ type: 'checkbox', options: ['a', 'b'], value: 2 }) // 👍 (value must match options type)
^^^^^^^^
Men jag skulle vilja lägga till en metod till den diskriminerade unionen och säkerställa att argumentet till den metoden också matchar värdetypen. Detta verkar inte vara möjligt:
type TextInput<Props extends Inputs<Props>> = {
type: 'text',
value?: string,
options?: undefined
} & Events<Props>
type CheckboxInput<Props extends Inputs<Props>> = {
type: 'checkbox',
options: string[] | number[],
value?: Props['options'] extends Array<infer T> ? T : never
} & Events<Props>
type Events<Props extends Inputs<Props>> = { onInput?: (arg: Inputs<Props>['value']) => any }
type Inputs<Props extends Inputs<Props>> = TextInput<Props> | CheckboxInput<Props>
type Make = <P extends Inputs<P>>(props: P) => {}
declare const create: Make
create({ type: 'checkbox', options: [1, 2, 3], value: 1, onInput: (arg) => arg }) // 👎 "arg" in onInput should only be a number, matching the value type
Fråga: Finns det något sätt att använda den inskränkta union-datan som argument för en metod inuti unionen?
Fullständig TypeScript-lekplats