我想将Component传递给包装器组件,包括要在包装器组件内部呈现的道具。 Typescript应该验证传递的道具是否属于传递的组件并进行类型检查。
这是传递给组件的道具:
act?:componentAct<T>
这部分起作用:
interface componentAct<T> {
component: React.ComponentType<T>,
props:T
}
interface WrapperProps<T> {
act?: componentAct<T>
}
interface ActorProps {
name: string
}
const Wrapper: React.SFC<WrapperProps<ActorProps>> = props => {
const componentAct = props.act
const Comp = componentAct!.component
return <Comp {...componentAct!.props}>{props.children}</Comp>
}
const Actor = (props: ActorProps) => {
return <div {...props}>test123</div>
}
const appNode = document.getElementById('app')
ReactDOM.render((<Wrapper act={{component: Actor, props:{name:'test'}}} />), appNode);
但是
React.SFC
>
我不想在这里传递ActorProps(而不是问号),因为包装器的props不知道Actor使用的是props,因为Wrapper在Actor的另一个库中。
这里的另一个问题是组件可能没有道具(然后应从componentAct中省略道具)
答案 0 :(得分:1)
如果您使用的是2.9或更高版本,则可以使用通用组件,该组件将允许您传递通用参数。我们还可以使用条件类型来使props
字段仅在组件具有道具时才需要:
interface componentAct<T> {
component: React.ComponentType<T>,
props: T
}
interface WrapperProps<T> {
act?: keyof T extends never ? { component: React.ComponentType<T>, props?: never } : componentAct<T>
}
interface ActorProps {
name: string
}
const Wrapper = function <T>(props: WrapperProps<T> & { children?: React.ReactNode }) {
const componentAct = props.act
const Comp = componentAct!.component
return <Comp {...componentAct!.props}>{props.children}</Comp>
}
const Actor = (props: ActorProps) => {
return <div {...props}>test123</div>
}
let ok = (<Wrapper<ActorProps> act={{ component: Actor, props: { name: 'test' } }} />)
let errorNoProp = (<Wrapper<ActorProps> act={{ component: Actor }} />) // Property 'props' is missing in type '{ component: (props: ActorProps) => Element; }'.
let errorExtraProp = (<Wrapper<ActorProps> act={{ component: Actor, props: { name: 'test', s: "" } }} />) // Object literal may only specify known properties, and 's' does not exist in type 'ActorProps'.
let errorForgottenGenericParam = (<Wrapper act={{ component: Actor, props: { name: 'test' } }} />)
const NoParams = () => {
return <div>test123</div>
}
let okNoPropsRequired = (<Wrapper act={{ component: NoParams }} />)
let errorPropsExtra = (<Wrapper act={{ component: NoParams, props: { bla: "" } }} />)