4

TypeScript: Interfaces vs Types对比与差别

 3 years ago
source link: https://www.myfreax.com/typescript-interfaces-vs-types/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

个人建议总是优先使用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

函数可以被typeinterface 修饰类型:

// 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映射。interfacetype 都可以修饰对象,那么我们应该使用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 关键词


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK