TS 中 type 和 interface 的区别

·  阅读 2478

事实上这两者非常的像,interface 能做的,type 基本都能做。但是两者还是有一些差别,这也就是本文想描述的事情。

1. interface 只能表示像对象那种结构的类型

interface 只能表示像对象那种结构的类型,如果想表示 JS 中的原始类型(undefined, null, boolean, stringnumber)只能交给 type 老大哥:

type A = string
复制代码

同时,type 也可以像 interface 一样表示对象类型,只不过语法有一点点不一样:

type Reptile = {
    genus: string
}
复制代码

另外,说一点,使用 interface 表示函数类型语法有点特殊:

interface SearchFunc {
    (source: string, subString: string): boolean;
}
复制代码

对比起来还是 type 表示函数更直观:

type SearchFunc = (source: string, subString: string) => boolean;
复制代码

2. type 可以动态计算属性,interface 没那么强大。

在 interface 中,我们可以这么来表示一个对象:

interface Y {
    [k: string]: number
}
复制代码

这里 k 的类型可以是 string 或者 number,但是只能这两个中的一个。上面代码中,我们指定 k 的类型是 string

type 在这方面就表现得更强大,它可以使用计算属性,可以限制属性包含某几个。

下面这个例子中, X 就只包含 小王小文 两个属性。

type Keys = "小王" | "小文"

type X = {
  [key in Keys]: string
}

const test: X = {
    '小王': '肌肉男',
    '小文': '也是肌肉男'
}
复制代码

interface 就不支持上面这种写法的,如果我们把上面的语法用在 interface,会报下面的错误:

image.png

下面是报错信息:

image.png

当然了,你可能会有疑问,interface 中使用 : 而不是 in 操作符呢?也不行。比如下面这个示例,也不支持下面这种组合 type 的写法:

type Keys = "小王" | "小文"

type X = {
  [key in Keys]: string
}

type XX = keyof Keys;

interface Y {
    [k: XX]: number
}

复制代码

image.png

总之 interface 中,表示对象的类型方面没 type 灵活。

3. type 声明的类型不能重名,interface 声明的重命名会合并在一块

比如下面这样,就报错了:

image.png

大家可以看这个线上例子

借助这个特性,我们想往全局的 window 属性上挂载一些自定义属性时,可以使用 interface:

interface Window {
    xxx: string;
}
复制代码

目前我就总结了上面三点的不同,其他一些不同是和错误信息展示有关的,不是很重要的就不罗列了。其实二者还是非常非常像的。一般来说,我们可以按照习惯一直使用一个,等遇到问题的时候,再考虑切换另外一个,也不需要太过于纠结,希望能帮到有选择焦虑症的同学:)

谢谢阅读,撒花!

分类:
前端
收藏成功!
已添加到「」, 点击更改