接口和类型别名之间是否存在语义差异?

use*_*776 6 typescript

我可以用接口和类型别名做大部分相同的事情。

例如

类可以实现接口或类型别名

interface Shape {
    area(): number;
}

type Perimeter = {
    perimeter(): number;
}

class Rectangle implements Shape, Perimeter {
}
Run Code Online (Sandbox Code Playgroud)

它们可以组合起来创建新的接口/类型别名

interface A {
    a: string;
}

type B = {
    b: string
}

interface C extends B {
    c: string;
}

type D = A & {
    d: string;
}
Run Code Online (Sandbox Code Playgroud)

接口和类型注释之间是否存在语义差异?

Pal*_*leo 3

interface和之间存在技术差异,type此处对此进行了详细描述

type然而,对于 a和 an都可以使用的情况interface,根本没有语义差异。

关于TypeScript 中的interface继承和type交集

在 TypeScript 中,接口之间的层次结构只是定义接口的一种方式。但一旦定义完毕,接口之间就不存在真正的父子关系。例如:

interface Named {
    name: string
}
interface Person extends Named {
    age: number
}
interface Animal {
    name: string
    age: number
}
Run Code Online (Sandbox Code Playgroud)

这里PersonAnimal是同一类型。一旦定义了它们,当其他代码使用它们时,编译器将以完全相同的方式处理它们:

function useNamed(named: Named) {
}
let p: Person = /* ... */
let a: Animal = /* ... */
useNamed(p) // OK
useNamed(a) // also OK, because if 'Animal' is compatible with
            // `Named` then it is a `Named`
Run Code Online (Sandbox Code Playgroud)

这就是为什么也可以使用交集类型创建相同的类型:

type Engine = Named & {
    age: number
}
Run Code Online (Sandbox Code Playgroud)

从规格来看:

交集类型表示同时具有多种类型的值。交集类型A & B的值是同时属于类型A和类型B的值。(来源: TypeScript 规范

我们的Engine类型既是 aNamed又是附加定义:它在语义上与接口继承相同。这里的 type与和Engine的类型完全相同。PersonAnimal