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

interface X {
    a: number
    b: string
}

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

当前回答

根据我最近看到或参与的所有讨论,类型和接口之间的主要区别在于接口可以扩展,而类型不能扩展。

此外,如果您两次声明一个接口,它们将被合并为一个接口。你不能用打字。

其他回答

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

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

其他答案很棒!Type可以做但Interface不能做的其他事情很少

可以在类型中使用联合

type Name = string | { FullName: string };

const myName = "Jon"; // works fine

const myFullName: Name = {
  FullName: "Jon Doe", //also works fine
};

在类型中迭代联合财产

type Keys = "firstName" | "lastName";

type Name = {
  [key in Keys]: string;
};

const myName: Name = {
  firstName: "jon",
  lastName: "doe",
};

类型中的交集(但是,在带有扩展的接口中也支持)

type Name = {
  firstName: string;
  lastName: string;
};

type Address = {
  city: string;
};

const person: Name & Address = {
  firstName: "jon",
  lastName: "doe",
  city: "scranton",
};

与接口相比,这种类型也不是后来才引入的,根据最新发布的TS类型,它几乎可以做任何接口可以做的事情,而且更多!


*除了声明合并(个人观点:很好,它在类型中不受支持,因为它可能导致代码不一致)

界面专门设计用于描述对象形状;然而,类型在某种程度上类似于可以用于为任何类型创建新名称的接口。

我们可以说,一个接口可以通过多次声明来扩展;而类型是封闭的。

https://itnext.io/interfaces-vs-types-in-typescript-cf5758211910

索引的差异。

interface MyInterface {
  foobar: string;
}

type MyType = {
  foobar: string;
}

const exampleInterface: MyInterface = { foobar: 'hello world' };
const exampleType: MyType = { foobar: 'hello world' };

let record: Record<string, string> = {};

record = exampleType;      // Compiles
record = exampleInterface; // Index signature is missing

相关问题:类型中缺少索引签名(仅在接口上,而不是在类型别名上)

因此,如果您想为对象编制索引,请考虑这个示例

看看这个问题和这个关于违反利斯科夫原则的问题

评估中的差异

当FirstLevelType为接口时,请查看ExtendeFirst的结果类型

/**
 * When FirstLevelType is interface 
 */

interface FirstLevelType<A, Z> {
    _: "typeCheck";
};

type TestWrapperType<T, U> = FirstLevelType<T, U>;


const a: TestWrapperType<{ cat: string }, { dog: number }> = {
  _: "typeCheck",
};

// {  cat: string; }
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _>
    ? T
    : "not extended";

当FirstLevelType为类型时,请查看ExtendeFirst的结果类型:


/**
 * When FirstLevelType is type
 */
type FirstLevelType<A, Z>= {
    _: "typeCheck";
};

type TestWrapperType<T, U> = FirstLevelType<T, U>;


const a: TestWrapperType<{ cat: string }, { dog: number }> = {
  _: "typeCheck",
};

// unknown
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _>
    ? T
    : "not extended";

在我的日常发展中,当我不知道该选择哪一个时,我会使用这个作弊表。

有关更多信息,请阅读我的博客:https://medium.com/@magenta2127/use-which-interface-or-type-alias-in-typescript-bdfaf2e882ae