如何允许一个函数接受多个不同的prop接口?在下面的示例中,我希望它接受IFlatProps
或IChildrenProps
。我尝试了以下操作,但似乎不起作用:
const Field: React.SFC<IFlatProps | IChildrenProps> = ({
label, name, helpText, children
}) => (
// ...
);
界面如下:
interface IFlatProps {
label: string;
name: string;
helpText?: string | JSX.Element;
}
interface IChildrenProps {
children: React.ReactNode;
helpText?: string | JSX.Element;
}
编辑:我从打字稿中得到的错误是:
[ts]类型'(IFlatProps&{子代?:ReactNode;})| (IChildrenProps &{儿童?:ReactNode; })'没有属性'label'和字符串 索引签名
此错误是由于label
属性引起的,我也遇到了与name
属性有关的错误。
这是一个复制问题的代码框:https://codesandbox.io/s/k5o20kvo4o
答案 0 :(得分:1)
问题在于,根据定义,您只能访问并集类型的公共字段,并且由于某些字段在两个接口之间不通用,因此您无法访问它们,因此也无法对它们进行解构。最简单的解决方案是将const
键入为SFC<IFlatProps|IChildrenProps>
,但是将函数的参数键入具有可选的所有联合成员的对象,例如Partial<IFlatProps & IChildrenProps>
const Field: React.SFC<IFlatProps | IChildrenProps> = ({
label, name, helpText, children // All typed as original type |undefined
}: Partial<IFlatProps & IChildrenProps>) => (
null
);
对于您而言,这很好,因为始终没有通用的强制属性,因此我们可以将所有属性视为参数上的可选属性。如果我们拥有此类属性,则可以使用更复杂的类型来保留这样的事实,即此类属性应始终存在
const Field: React.SFC<IFlatProps | IChildrenProps> = ({
label, name, helpText, children, //these are still optional
commonNotOptional //will be just string
}: Merge<IFlatProps, IChildrenProps>) => null;
type Merge<T1, T2> = Pick<T1, Extract<keyof T1, keyof T2>> &
Pick<T2, Extract<keyof T2, keyof T1>> &
Partial<T1 & T2>
interface IFlatProps {
label: string;
name: string;
commonNotOptional: string
helpText?: string | JSX.Element;
}
interface IChildrenProps {
children: React.ReactNode;
helpText?: string | JSX.Element;
commonNotOptional: string
}