【发布时间】:2018-07-04 06:11:12
【问题描述】:
我有一个组件连续多次使用,具有一些相同的属性和一些独特的属性:
interface InsideComponentProps {
repeatedThing: string;
uniqueThing: string;
}
const InsideComponent: React.SFC<InsideComponentProps> = ({ repeatedThing, uniqueThing }) => (
<div>{repeatedThing} - {uniqueThing}</div>
);
const Example = () => (
<div>
<InsideComponent repeatedThing="foo" uniqueThing="1" />
<InsideComponent repeatedThing="foo" uniqueThing="2" />
<InsideComponent repeatedThing="foo" uniqueThing="3" />
</div>
);
重复的repeatedThing 属性困扰着我,所以我正在寻找一种方法来消除这种冗余。我在非 TypeScript 应用程序中做过的一件事是引入了一个包装器组件,它可以克隆所有子级,并在此过程中添加重复的属性:
interface OutsideComponentProps {
repeatedThing: string;
}
const OutsideComponent: React.SFC<OutsideComponentProps> = ({ repeatedThing, children }) => (
<div>
{React.Children.map(children, (c: React.ReactElement<any>) => (
React.cloneElement(c, { repeatedThing })
))}
</div>
);
const Example = () => (
<OutsideComponent repeatedThing="foo">
<InsideComponent uniqueThing="1" />
<InsideComponent uniqueThing="2" />
<InsideComponent uniqueThing="3" />
</OutsideComponent>
);
生成的 JavaScript 代码具有我想要的行为,但 TypeScript 编译器出现错误,因为我在实例化 InsideComponent 时没有传递所有必需的属性:
ERROR in [at-loader] ./src/index.tsx:27:26
TS2322: Type '{ uniqueThing: "1"; }' is not assignable to type 'IntrinsicAttributes & InsideComponentProps & { children?: ReactNode; }'.
Type '{ uniqueThing: "1"; }' is not assignable to type 'InsideComponentProps'.
Property 'repeatedThing' is missing in type '{ uniqueThing: "1"; }'.
我想到的唯一解决方案是将InsideComponents repeatedThing 属性标记为可选,但这并不理想,因为该值是必需的。
如何保持严格性,确保InsideComponent 确实收到所有道具,同时减少调用站点上的属性重复?
我正在使用 React 16.2.0 和 TypeScript 2.6.2。
【问题讨论】:
-
请注意,指定回调参数类型,虽然不是这里的原因,但会产生尴尬的类型错误并隐藏真正的错误。
map(components, (c: React.ReactElement<any>) => ...)应该是map, components, c => ...) -
@AluanHaddad 我从How to assign the correct typing to React.cloneElement when giving properties to children? 收集到的;你是说答案不正确?
-
不,我并不是说答案不正确。他正在使用类型断言
c as ReactElement<any>,在必要时这是一种很好的风格,就像那个答案一样。您将类型断言隐藏在(c: ReactElement<any>) =>后面。这是一种不好的风格,因为您实际上使用了一个断言as,但我们只有通过阅读map的定义才能知道这一点。
标签: reactjs typescript