当我们计划使用Typescript在React App中,我们需要去阅读typescript handbook,或者尝试使用React脚手架工具create-react-app
去构建一个已经集成了typescript去做一个demo。我们经常会看到这样一个代码段
interface Props {
message: string;
userName: string;
}
显而易见,它是为了对于传入组件内部Props的类型声明。与此同时,typescript提供一个译作类型别名(type alias)的东西。如果是之前使用过facebook提供的强类型工具flow
的同学,可能更加疑惑。
- 这两个哥们究竟有什么区别?
- 我们在typescript 继续使用
type
去声明类型会存在什么问题么? - 我们是否可以设置一个规范去保证项目统一?
Okay. That's fine. 问题千万个,文档第一步。我们看看官方文档怎么解释的。
As we mentioned, type aliases can act sort of like interfaces; however, there are some subtle differences.
One difference is that interfaces create a new name that is used everywhere. Type aliases don’t create a new name — for instance, error messages won’t use the alias name. In the code below, hovering over interfaced in an editor will show that it returns an Interface, but will show that aliased returns object literal type.
纳尼??? what are you talking about ??? 这尼玛鬼看的懂。强类型关EDI屁事。
那么我们看看这两个哥们在实际用法上有什么差异。直接上表~(来自: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types)
aspect | type | interface |
---|---|---|
can describe functions | Yes | Yes |
can describe constructors | Yes | Yes |
can describe tuples | Yes | Yes |
interface can extend it | Warning | Yes |
Classes can implements it | No | Yes |
Can intersect another one of its kind | Yes | Warning |
Can create a union with another one of its kind | Yes | No |
Can be used to create mapped types | Yes | No |
Can be mapped over withe mapped types | Yes | Yes |
Expands in error message and logs(?) | Yes | No |
Can be augmented | No | No |
Can be recursive | Warning | Yes |
我们再来找几个实际的代码段看看
// the result of them are the same.
type CountA = (start: number) => string
interface CountB {
(x: number, y: number): void;
}
type CountC = {
interval: number
reset: () => void
}
interface CountD = {
interval: number
reset: () => void
}
type CountE = CountA & CountC
interface CountF extends CountB, CountD {}
所以看出什么了么?
- 两者通过不同的语法得到了相同的结果。
- 根据官方文档所说,如果构建的是公开第三方库的类型,还是建议使用interface.
- 根据表格上可以看出,interface 更倾向于继承;而 type 则更倾向于组合。
所以我们应该如何使用?
老祖宗说过,组合优于继承。尤其是对于我们使用的React框架来说。
the mental model for React is more functional. In other words, React is more functional by nature. Functional components are generally preferred over class-based components. Hot and shiny React Hooks are just functions used inside functional components.
所以就个人而言,我更建议使用 type 来定义 state 和 props。保持团队项目声明一直。