嵌套对象属性的Typescript泛型



我想实现这样的东西,以便可以推断Component的类型,从而可以自动安全地键入props

type ComponentsType<T extends React.FC<any>> {
[key: string]: {
Component: T;
props?: React.ComponentProps<T>
};
}
const components: ComponentsType = {
RedButton: {
Component: Button,
props: { // <- this should be automatically typed to take props of Button
color: 'red'
}
},
BlueButton: {
Component: Button,
props: { // <- this should be automatically typed to take props of Button
color: 'blue'
}
},
FullWidthCard: {
Component: Card,
props: { // <- this should be automatically typed to take props of Card
variant: 'full-width'
}
},
}

但是上面的输入不起作用,因为泛型部分位于对象的根(AKAcomponents)上,而不是位于每个属性(AKARedButtonFullWidthCard)上。

那么typescript有没有办法一个一个地遍历它们,一个一个地推断出组件呢?

感谢

为了实现预期的行为,您需要从函数参数中推断出每个组件和道具。我的意思是,你需要创建一个额外的函数。

import React, { FC, ComponentProps } from 'react'

const Button: FC<{ color: string }> = (props) => null
const Card: FC<{ variant: string }> = (props) => null

type WithProps<T> =
T extends Record<infer Key, infer _> ? {
[P in Key]: T[Key] extends { Component: infer Comp, props: infer PassedProps }
? Comp extends React.JSXElementConstructor<infer Prps>
? { Component: Comp, props: ComponentProps<Comp> & Record<Exclude<keyof PassedProps, keyof Prps>, never> }
: never
: never
} : never

const components = <
Comp extends React.JSXElementConstructor<any>,
Item extends { Component: Comp },
Components extends Record<string, Item>>(dictionary: Components & WithProps<Components>) => {}

游乐场

Comp-推断组件

Item-推断字典项,component&props对象

Components-推断出整个参数

WithProps-遍历传递参数的每个对象,并检查props对象是否可分配给组件道具。如果是-返回道具,否则否定所有无效的道具到never

components({
RedButton: {
Component: Button,
props: {
color: 'red'
}
},
BlueButton: {
Component: Button,
props: {
extra_prop:42, // DRAWBACK, no error
color: 'blue'
}
},
FullWidthCard: {
Component: Card,
props: {
variant_invalid_prop: 'full-width' // expected error
}
},
})

但是有一个缺点,这个函数会接受额外的道具,比如extra_prop

注:我希望有人能提出更好的解决方案,额外的道具也将无效

相关内容

  • 没有找到相关文章

最新更新