需求类似json表单,通过json数组配置来实现一些功能。
比如https://segmentfault.com/q/1010000044539938,但是它这个是单项配置。
有如下ts代码:
type Component = Record<string, any>
const input: { readonly?: boolean } = {} satisfies Component
const select: { options?: any[] } = {} satisfies Component
const components = { input, select } as const satisfies Record<string, Component>
type DefinedComponents = typeof components
type DefinedComponentType = keyof DefinedComponents
type Item<Type extends (DefinedComponentType | Component)> = {
type: Type,
props: Type extends DefinedComponentType ? DefinedComponents[Type] : Type
}
function createItem<Type extends (DefinedComponentType | Component)>(item: Item<Type>) {}
createItem({ type: 'input', props: { readonly: false } })
createItem({ type: {} as { customProps?: number }, props: { customProps: 0 } })
可以看到对于单项配置是没问题的,然后想实现数组配置:
function createItems<Type extends (DefinedComponentType | Component)>(items: Item<Type>[]) {}
createItems([
{ type: 'input', props: { readonly: false } },
{ type: 'select', props: { options: [] } }
])
这里 createItems
中的 props
会推断成 { readonly?: boolean } | { options?: any[] }
,也就是 input
和 select
的联合类型,这也好理解,因为泛型 Type
现在是 'input' | 'select'
。
那要怎么修改 createItems
的参数类型,才能实现 type
为 'input'
时,props
能正确推断为 { readonly?: boolean }
,'select'
或者自定义 type
同理?
playground