【问题标题】:How can one extend React types to support html attributes as props?如何扩展 React 类型以支持 html 属性作为道具?
【发布时间】:2018-11-10 15:43:42
【问题描述】:

给定一个带有自定义 props 和 html 属性 props 的组件,应该如何创建这样一个组件的接口?理想情况下,该接口还将处理特定于 react 的 html 道具,例如使用 className 而不是 class

这是我试图找到正确接口的用法示例:

<MyComponent customProp='value' style={{textAlign: 'center'}}  />

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:
    interface IMyComponentProps extends React.HTMLAttributes<HTMLElement> {
      customProp: string;
    }
    

    更新: @ddek 提到了路口&amp;

    我想警告您有关该方法的以下问题。

    
    interface A {
      onClick: () => void;
    }
    
    interface B {
      onClick: (event: React.MouseEvent<HTMLElement>) => void;
    }
    
    // Typescript does not complain. This is not good
    type AB = A & B;
    const a: AB = {
      onClick: () => {}
    };
    
    
    // TS2320: Interface 'AB2' cannot simultaneously extend types 'A' and 'B'.
    // Named property 'onClick' of types 'A' and 'B' are not identical.
    
    interface AB2 extends A, B {
    
    }
    
    // TS2430: Interface 'AC' incorrectly extends interface 'A'.
    //   Types of property 'onClick' are incompatible.  
    //   Type '(event: MouseEvent<HTMLElement, MouseEvent>) => void' is not
    // assignable to type '() => void'.
    interface AC extends A {
      onClick: (event: React.MouseEvent<HTMLElement>) => void;
    }
    
    

    【讨论】:

    【解决方案2】:

    Yozi 是对的,但还有另一种方法,它演示了一个 typescript(和通用 FP)功能,如果您来自 C# 或 Java 之类的东西,您可能不熟悉。

    interface MyCustomProps {
        customProp: string;
    }
    
    const MyComponent = (props: MyCustomProps & React.HTMLAttributes<...>) 
        => (...)
    

    在打字稿中,类型声明中的&amp; 指的是交集类型You can read more in the typescript docsprops 对象现在结合了 MyCustomProps 的属性和 HTML 属性。 (关于有区别的联合或or 类型也值得学习,它们用| 表示。我发现这些比交集更有用)。

    如果你想清理你的方法签名,你可以声明类型如下:

    interface MyCustomProps {...}
    type ComponentProps = MyCustomProps & React.HTMLAtributes<...>;
    

    但是,这种表示法现在已经失去了之前两种方法的简洁性——extends 语法和&amp; 表示法。

    【讨论】:

    • 我建议使用extend 而不是&amp;
    • 你为什么推荐这种方法@yozi?
    • @sunpietro 它有不同的语义。一个是extend,另一个是intersection。请参阅我对这个问题的回答。在我写它的时候,Typescript 对&amp; 不够准确,我听说 Typescript 团队有计划修复它,但是如果你可以简单地使用 extend,那么依赖“修复”的原因是什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 2010-12-04
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2019-09-17
    相关资源
    最近更新 更多