【问题标题】:typed react - props as `type` or an `interface`类型化的反应 - 道具作为 `type` 或 `interface`
【发布时间】:2018-09-08 19:05:10
【问题描述】:

我有反应代码

export default class MyComponent extends Component<Props,State>

问题是,我是写像type 还是interface 这样的道具?

type Props = {
    isActive: Boolean,
    onClick: Function
}

interface Props {
    isActive: Boolean,
    onClick: Function
}

另外,当我不使用打字稿,而是使用经典的 webpack+babel 设置时,有什么区别?

或者,这对我来说很重要吗?

【问题讨论】:

    标签: reactjs typescript flowtype


    【解决方案1】:

    现在是 2020 年,在几乎所有使用 React 道具的情况下,我都会支持 type(一般类型与界面帖子是 here)。只能用类型别名表示的常见情况:

    // given some props from another comp that are to be altered
    type ExternalProps = { a: string; b: { c: number } };
    
    type Props_IndexType = ExternalProps["b"]; // { c: number; }
    type Props_MappedType = { [K in keyof ExternalProps]: number }; // { a: number; b: number; }
    type Props_DiscriminatedUnionType = { tag: "tag1"; foo: string } | { tag: "tag2"; foo: boolean}
    type Props_typeOf = { foo: string } & typeof defaultProps; // see class comp example
    
    // conditional types - ok, this one is a bit contrived, but you get the point
    type Props_ConditionalType<T> = T extends true ? { a: string } : { b: number };
    const Comp = <T extends {}>(props: Props_ConditionalType<T>) =>
      <div>{"a" in props && (props as any).a}</div>
    render(<Comp<true> a="foo" />, document.getElementById("root"));
    

    类组件example 用于说明(OP 提到了它们,但上述情况也适用于 Hooks):

    // cannot do that with interfaces
    type Props = ({ tag: "tag1"; foo: string } | { tag: "tag2"; foo: boolean }) &
      typeof defaultProps;
    type State = typeof initState;
    
    const defaultProps = { a: "A" };
    const initState = { c: "C" };
    
    class App extends React.Component<Props, State> {
      static readonly defaultProps = defaultProps;
      state = initState;
    
      render() { ... }
    }
    
    render(<App tag="tag1" foo="foo" />, document.getElementById("root"));
    

    唯一的情况,我会考虑接口:

    • 您在全球范围内使用 declaration merging 的 prop 类型(现在不常见)
    • 您想隐藏类型实现细节,因为接口会创建一个新名称,用于错误消息、IDE 类型信息等 (docs)

    【讨论】:

      【解决方案2】:

      接口比对应的类型声明要强大一点,但是对于一组 react props 来说,这可能无关紧要。 您可以阅读有关类型和接口之间的区别in this question

      由于您不太可能扩展该界面或在其他地方扩充它,因此使用其中任何一个都可能没问题。但我想说,定义对象类型通常首选接口,因为它们更灵活。

      【讨论】:

      • 这个答案可能已经过时了。至于“更强大”的部分,也可以很容易地提出相反的观点。签出:stackoverflow.com/questions/37233735/…。关于接口是否真的“更好”,网上也有更多的讨论。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2017-09-26
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多