TypeScript中的这些语句(接口与类型)有什么区别?

interface X {
    a: number
    b: string
}

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

当前回答

除了已经提供的出色答案之外,在扩展类型和接口方面还有明显的区别。我最近遇到了一些界面无法完成任务的情况:

无法使用接口扩展联合类型无法扩展通用接口

其他回答

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

一个区别是,接口创建了一个新名称,该名称在任何地方都可以使用。键入别名不会创建新名称-例如,错误消息不会使用别名。

2021 3月更新:更新的TypeScript手册(也在nju-clc中提到下面的答案)有一节“接口与类型别名”,解释了区别。


原始答案(2016)

根据(现已存档)TypeScript语言规范:

与总是引入命名对象类型的接口声明不同,类型别名声明可以引入任何类型的名称,包括基元类型、联合类型和交集类型。

该规范还提到:

接口类型与对象类型的类型别名有许多相似之处但是由于接口类型提供了更多的功能通常优选键入别名。例如,接口类型接口点{x: 数量;y: 数量;}可以写成类型别名类型点={x: 数量;y: 数量;};但是,这样做意味着失去以下功能:接口可以在extends或implements子句中命名,但对象类型文本的类型别名不能在TS 2.7之后为true。接口可以有多个合并声明,但对象类型文本的类型别名不能。

类型示例:

//为对象创建树结构。由于缺少交集(&),您无法对接口执行相同的操作

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

//键入以限制变量仅分配几个值。接口没有联合(|)

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

//由于类型,您可以通过条件机制声明NonNullable类型。

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

界面示例:

//您可以使用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)
    }
}

//可以使用其他接口扩展接口

    interface IMyObject {
        label: string,
    }

    interface IMyObjectWithSize extends IMyObject{
        size?: number
    }

除了已经提供的出色答案之外,在扩展类型和接口方面还有明显的区别。我最近遇到了一些界面无法完成任务的情况:

无法使用接口扩展联合类型无法扩展通用接口

“typescriptlang”似乎建议尽可能使用接口而不是类型。接口与类型别名