接口 A 错误地扩展了接口 B

Jan*_*imo 6 typescript reactjs

给定这个接口:

interface Props extends React.HTMLAttributes<HTMLDivElement> {
  compLevel: string;
  property: Property;
  comps: Property[];
}
Run Code Online (Sandbox Code Playgroud)

property鉴于该属性已经存在于HTMLAttributesas上,我对该属性遇到了困难property?: string;:

接口“Props”错误地扩展了接口“HTMLAttributes”。财产“财产”的类型是不兼容的。类型“SerializedObject”不可分配给类型“string”。

重命名属性是可行的,尽管我不想这样做。推荐的扩展/使用方法是什么接口,这样我就不需要重新定义className我的Props?

jca*_*alz 7

你要做什么Props?您可能不应该在需要React.HTMLAttributes<HTMLDivElement>. 如前所述,并将代码视为一个完整的示例,我可能会Props这样定义:

// SimpleSpread<L, R> is a simplified version of what happens when you
// do an object spread like {...left, ...right} where left is of type L and
// right is of type R.  It is the type R, with any properties on L that
// don't exist in R.  (It doesn't work if a key in L is an optional property in
// R, which is why this is simplified)
type SimpleSpread<L, R> = R & Pick<L, Exclude<keyof L, keyof R>>;

// Define the props you want to spread into React.HTMLAttributes<HTMLDivElement>
interface PropsExtra {
  compLevel: string;
  property: Property;
  comps: Property[];
}

// Define Props
interface Props
  extends SimpleSpread<React.HTMLAttributes<HTMLDivElement>, PropsExtra> {}
Run Code Online (Sandbox Code Playgroud)

这是通过仅处理那些Props未出现在中的属性来实现的。所以这最终会覆盖该属性而不是扩展它。PropsExtraReact.HTMLAttributes<HTMLDivElement>PropsExtraproperty

现在就没有错误了。


请注意,以下内容将出现错误:

declare function acceptAttributes(attrs: React.HTMLAttributes<HTMLDivElement>);
declare const p: Props;
acceptAttributes(p); // error! p is not a React.HTMLAttributes<HTMLDivElement>
Run Code Online (Sandbox Code Playgroud)

因为它们的属性类型不同property(呵呵),所以 type 的值Props不再是有效值React.HTMLAttributes<HTMLDivElement>。任何期待后者的事物都不会接受前者。然后,您可以更改此类函数的预期参数类型,这可能会向外级联,直到此更改涉及的代码库超出您的预期。

因此,这是否适合您实际上取决于您的用例。祝你好运!


小智 0

由于 HTMLAttribute 上已经存在“property”属性,因此我可以看到三种继续前进的方法:

  1. 将属性重命名为另一个更精确的术语,该术语不与现有属性重叠(例如 propsProperty)
  2. 如果值在某种程度上相似,则可以将该属性转换为 SerializedObject 以匹配类型签名
  3. 将属性重命名为 _property,并将接口的 getter 和 setter 设置为从 _property 而不是 property 更改。(还没有测试过这个)