TS中interface
(接口)和type
(类型别名)有许多相似之处:
- 实际开发中两者都可以用来约束变量的类型
- 两者都可以扩展
- 接口和类型别名不是互斥的,接口可以扩展类型别名,反之亦然
下面主要来看下区别
1、声明方式不同
interface Point {
x: number;
y: number;
}
interface SetPoint {
(x: number, y: number): void;
}
type Point = {
x: number;
y: number;
};
type SetPoint = (x: number, y: number) => void;
2、类型别名(type
)还可以用于其他类型,如基本类型(原始值)、联合类型、元组
// primitive
type Name = string;
// union
type PartialPoint = PartialPointX | PartialPointY;
// tuple
type Data = [number, string];
// dom
let div = document.createElement('div');
type B = typeof div;
3、扩展时语法不同,且interface
无法扩展联合类型的type
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
type PartialPoint = { x: number; } | { y: number; };
// 报错:无法实现一个联合类型的type
// class SomePartialPoint implements PartialPoint {
// x: 1;
// y: 2;
// }
4、interface
可以定义多次,并将被视为单个接口(合并所有声明的成员);type
不可以
interface Point { x: number; }
interface Point { y: number; }
const point: Point = { x: 1, y: 2 };
5、interfac可以extends
class,class也可以implements
interface
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
interface Foo {
name: string;
age: number;
sayHello(): void;
}
class Bar implements Foo {
name: string;
age: number;
sayHello(): void {
console.log('Hello');
}
}
6、type
支持计算属性,生成映射类型,interface
不可以
type
能使用in
关键字生成映射类型,但interface
不行- 语法与索引签名的语法类型,内部使用了
for .. in
type Keys = "firstname" | "surname"
type DudeType = {
[key in Keys]: string
}
const test: DudeType = {
firstname: "Pawel",
surname: "Grzybek"
}
// 报错
//interface DudeType2 {
// [key in keys]: string
//}
总结:我平时开发中,习惯在一个module下新建一个公共文件interface.ts
,专门export各种interface,用于约束当前module业务代码中各种变量的类型和取值范围;如果单独某个组件中的变量取值范围比较特殊,那就在其组件业务代码中用type约束下
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。