typed react - props为`type`或`interface`

时间:2018-03-29 18:08:40

标签: reactjs typescript flowtype

我有反应代码

export default class MyComponent extends Component<Props,State>

问题是,我是否撰写了像typeinterface这样的道具?

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

interface Props {
    isActive: Boolean,
    onClick: Function
}

另外,当我不使用打字稿时,还有经典的webpack + babel设置时,有什么可怕的呢?

或者,它对我来说甚至重要吗?

2 个答案:

答案 0 :(得分:4)

接口比相应的类型声明更强大,但对于一组反应道具,它可能无关紧要。 您可以阅读类型和接口in this question之间的差异。

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

答案 1 :(得分:4)

现在是2020年,在几乎所有带有type道具的情况下,我都倾向于使用React(通用类型vs接口帖子为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处理道具类型(如今不常见)
  • 您要隐藏类型实现的详细信息,因为接口会在错误消息,IDE类型信息等中创建新名称。(docs