What is the difference between these statements (interface vs type)? 这些语句(接口与类型)之间有什么区别?

interface X {
    a: number
    b: string
}

type X = {
    a: number
    b: string
};

#1楼



#2楼

Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind of type, including primitive, union, and intersection types. 与始终引入命名对象类型的接口声明不同, 类型别名声明可以为任何类型的类型引入名称,包括基元,联合和交集类型。

The specification goes on to mention: 规范接着提到:

Interface types have many similarities to type aliases for object type literals, but since interface types offer more capabilities they are generally preferred to type aliases. 接口类型与对象类型文字的类型别名有很多相似之处,但由于接口类型提供了更多功能,因此通常首选键入别名。 For example, the interface type 例如,接口类型

interface Point { x: number; y: number; }

could be written as the type alias 可以写为类型别名

type Point = { x: number; y: number; };

However, doing so means the following capabilities are lost: 但是,这样做意味着丢失了以下功能:

  • An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot 接口可以在extends或implements子句中命名,但是 从TS 2.7开始 ,对象类型文字的类型别名不能 再为真。
  • An interface can have multiple merged declarations , but a type alias for an object type literal cannot. 接口可以有多个合并声明 ,但对象类型文字的类型别名不能。

#3楼

https://www.typescriptlang.org/docs/handbook/advanced-types.html https://www.typescriptlang.org/docs/handbook/advanced-types.html

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. 类型别名不会创建新名称 - 例如,错误消息将不使用别名。


#4楼

2019 Update 2019年更新


The current answers and the official documentation are outdated. 目前的答案和官方文件已经过时。 And for those new to TypeScript, the terminology used isn't clear without examples. 对于那些刚接触TypeScript的人来说,如果没有示例,使用的术语就不清楚了。 Below is a list of up-to-date differences. 以下是最新差异列表。

1. Objects / Functions 1.对象/功能

Both can be used to describe the shape of an object or a function signature. 两者都可用于描述对象的形状或函数签名。 But the syntax differs. 但语法不同。

Interface 接口

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

Type alias 输入别名

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

2. Other Types 2.其他类型

Unlike an interface, the type alias can also be used for other types such as primitives, unions, and tuples. 与接口不同,类型别名也可用于其他类型,例如基元,联合和元组。

// primitive
type Name = string;

// object
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union
type PartialPoint = PartialPointX | PartialPointY;

// tuple
type Data = [number, string];

3. Extend 3.延伸

Both can be extended, but again, the syntax differs. 两者都可以扩展,但同样,语法也不同。 Additionally, note that an interface and type alias are not mutually exclusive. 另外,请注意,接口和类型别名不是互斥的。 An interface can extend a type alias, and vice versa. 接口可以扩展类型别名,反之亦然。

Interface extends interface 接口扩展接口

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

Type alias extends type alias 类型别名扩展类型别名

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

Interface extends type alias 接口扩展类型别名

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

Type alias extends interface 类型别名扩展接口

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

4. Implements 4.实施

A class can implement an interface or type alias, both in the same exact way. 类可以以相同的方式实现接口或类型别名。 Note however that a class and interface are considered static blueprints. 但请注意,类和接口被视为静态蓝图。 Therefore, they can not implement / extend a type alias that names a union type. 因此,它们无法实现/扩展名为联合类型的类型别名。

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x: 1;
  y: 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x: 1;
  y: 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x: 1;
  y: 2;
}

5. Declaration merging 5.宣言合并

Unlike a type alias, an interface can be defined multiple times, and will be treated as a single interface (with members of all declarations being merged). 与类型别名不同,接口可以多次定义,并将被视为单个接口(所有声明的成员都被合并)。

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };

#5楼

As of TypeScript 3.2 (Nov 2018), the following is true: 从TypeScript 3.2(2018年11月)开始,以下情况属实:


#6楼

Examples with Types: 类型示例:

// create a tree structure for an object. //为对象创建树结构。 You can't do the same with interface because of lack of intersection (&) 由于缺少交叉(&),您无法对界面执行相同操作

type Tree<T> = T & { parent: Tree<T> };

// type to restrict a variable to assign only a few values. //键入以限制变量仅分配几个值。 Interfaces don't have union (|) 接口没有联合(|)

type Choise = "A" | "B" | "C";

// thanks to types, you can declare NonNullable type thanks to a conditional mechanism. //感谢类型,你可以通过条件机制声明NonNullable类型。

type NonNullable<T> = T extends null | undefined ? never : T;

Examples with Interface: 接口示例:

// you can use interface for OOP and use 'implements' to define object/class skeleton //您可以使用OOP接口并使用'implements'来定义对象/类骨架

interface IUser {
    user: string;
    password: string;
    login: (user: string, password: string) => boolean;
}

class User implements IUser {
    user = "user1"
    password = "password1"

    login(user: string, password: string) {
        return (user == user && password == password)
    }
}

// you can extend interfaces with other interfaces //您可以扩展其他接口的接口

interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }