try to descript a type for filling data of form item.
value's type depends on type of form item.
enum AntdInputType {
InputText = 'InputText',
DatePicker = 'DatePicker',
TreeSelect = 'TreeSelect',
// ...
}
type ValueOfTypeMap = {
[AntdInputType.InputText]: string,
[AntdInputType.DatePicker]: string | Date,
[AntdInputType.TreeSelect]: string[],
// ...
}
// value's type related to 'type' property
type FillFormItem<Type extends keyof ValueOfTypeMap> = {
label: string
type: Type
value: ValueOfTypeMap[Type]
}
// it can check the type of value correctly
const fill: FillFormItem<AntdInputType.InputText> = {
label: 'test',
type: AntdInputType.InputText,
value: 'word',
// this will cause error for good
// value: ['word']
}
// but for array of FillFormItem will not work
const fillValues: FillFormItem<keyof ValueOfTypeMap>[] = [
{
label: 'text',
type: AntdInputType.InputText,
// here will pass, because value's type become unions type (string | Date | string[])
value: ['text'],
}
]
I think i use the wrong way to define "array of FillFormItem"
here's the playground
CodePudding user response:
You need to create a union of all allowed states. See here:
enum AntdInputType {
InputText = 'InputText',
DatePicker = 'DatePicker',
TreeSelect = 'TreeSelect',
// ...
}
type ValueOfTypeMap = {
[AntdInputType.InputText]: string,
[AntdInputType.DatePicker]: string | Date,
[AntdInputType.TreeSelect]: string[],
}
type FillFormItem<Type extends keyof ValueOfTypeMap> = {
label: string
type: Type
value: ValueOfTypeMap[Type]
}
type MappedUnion<
Keys extends string,
KeyValues extends Record<Keys, unknown>
> = {
[Prop in Keys]: {
label: string,
type: Prop,
value: KeyValues[Prop]
}
}[Keys]
type Union = MappedUnion<AntdInputType, ValueOfTypeMap>
const fill: Union = {
label: 'text',
type: AntdInputType.InputText,
value: 'word',
}
const fillValues: Union[] = [
{
label: 'text',
type: AntdInputType.TreeSelect,
value: ['text',]
}
]
Union
is a discriminated union. Treat property type
as discriminator. Once you provide allowed value for type
- TS knows all other properties and is able to validate them