个人建议总是优先使用interface
接口
什么时候使用Type?
- 定义原始类型时
- 定义元组tuple类型时
- 定义函数时
- 定义联合类型时
- 当你需要重载对象的函数的时
- 当你需要映射类型的优点时
什么时候使用接口
- 对于上面的所有其它情况下个人推荐使用
interface
- 当你想使用合并声明的优点使用
interface
原始类型Primitive types
最简单的方式查看type
和接口interface
的不同,只有type
可以用于原始类型的别名
type Nullish = null | undefined;
type Fruit = 'apple' | 'pear' | 'orange';
type Num = number | bigint;
这些都是不能用interfaces实现的。
💡当你需要定义一个原始类型的别名时,请使用type
关键词声明
元组类型Tuple types
Tuples只可以使用type
关键词声明:
type row = [colOne: number, colTwo: string];
💡 定义元组类型时使用type
关键字。
函数类型Function types
函数可以被type
和interface
修饰类型:
// via type
type Sum = (x: number, y: number) => number;
// via interface
interface Sum {
(x: number, y: number): number;
}
由于可以使用两种方式都能实现相同的效果,因此在函数修饰类型上的方案是使用type
,因为它更易读更快捷。
💡 当修饰函数类型时使用 type
Union types 联合类型
联合类型只能通过type
关键词声明
type Fruit = 'apple' | 'pear' | 'orange';
type Vegetable = 'broccoli' | 'carrot' | 'lettuce';
// 'apple' | 'pear' | 'orange' | 'broccoli' | 'carrot' | 'lettuce';
type HealthyFoods = Fruit | Vegetable;
💡 当定义联合类型时使用type
关键词
Object types对象类型
一个对象在javascript中式key/value的映射,对象类型在typescript使用类型修饰,也是key/value映射。interface
和type
都可以修饰对象,那么我们应该使用type
还是interface
对于对象类型
交集与继承
使用types的组合我们可以做到下面操作:
type NumLogger = {
log: (val: number) => void;
}
type StrAndNumLogger = NumLogger & {
log: (val: string) => void;
}
const logger: StrAndNumLogger = {
log: (val: string | number) => console.log(val)
}
logger.log(1)
logger.log('hi')
如果我们改用interfaces接口尝试:
interface NumLogger {
log: (val: number) => void;
}
interface StrAndNumLogger extends NumLogger {
log: (val: string) => void;
};
StrAndNumLogger
声明将会给出一个错误:
在使用interfaces接口的情况下,子类的类型声明必须完全匹配父类,否则TS将会抛出上面的错误。
💡 当你尝试在对象上重载函数类型时,使用type
会更好。
Mapped object types映射对象类型
使用type
关键词,我们可以获得映射类型的所有好处,像下面的代码。
type Fruit = 'apple' | 'orange' | 'banana';
type FruitCount = {
[key in Fruit]: number;
}
const fruits: FruitCount = {
apple: 2,
orange: 3,
banana: 4
};
这是使用interfaces接口做不到的
type Fruit = 'apple' | 'orange' | 'banana';
// ERROR:
interface FruitCount {
[key in Fruit]: number;
}
💡 当需要映射类型的好处时使用type
关键词