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

interface X {
    a: number
    b: string
}

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

当前回答

索引的差异。

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";

其他回答

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

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

TypeScript手册给出了答案:

界面的几乎所有功能都是可用的类型。关键区别在于不能重新打开类型以添加新的财产vs始终可扩展的接口。

接口与类型

接口和类型用于描述对象和原语的类型。接口和类型通常可以互换使用,并且通常提供类似的功能。通常由程序员选择自己的偏好。

然而,接口只能描述创建这些对象的对象和类。因此,必须使用类型来描述字符串和数字等原语。

下面是接口和类型之间的两个区别的示例:

// 1. Declaration merging (interface only)

// This is an extern dependency which we import an object of
interface externDependency { x: number, y: number; }
// When we import it, we might want to extend the interface, e.g. z:number
// We can use declaration merging to define the interface multiple times
// The declarations will be merged and become a single interface
interface externDependency { z: number; }
const dependency: externDependency = {x:1, y:2, z:3}

// 2. union types with primitives (type only)

type foo = {x:number}
type bar = { y: number }
type baz = string | boolean;

type foobarbaz = foo | bar | baz; // either foo, bar, or baz type

// instances of type foobarbaz can be objects (foo, bar) or primitives (baz)
const instance1: foobarbaz = {y:1} 
const instance2: foobarbaz = {x:1} 
const instance3: foobarbaz = true 

2019年更新


目前的答案和官方文件已经过时。对于那些新接触TypeScript的人来说,如果没有例子,使用的术语就不清楚了。以下是最新差异列表。

1.对象/功能

两者都可以用来描述对象或函数签名的形状。但语法不同。

界面

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

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

类型别名

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

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

2.其他类型

与接口不同,类型别名也可以用于其他类型,如基元、联合和元组。

// primitive
type Name = string;

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

// union
type PartialPoint = PartialPointX | PartialPointY;

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

3.延伸

两者都可以扩展,但语法也不同。此外,请注意,接口和类型别名不是互斥的。接口可以扩展类型别名,反之亦然。

接口扩展接口

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

类型别名扩展类型别名

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

接口扩展类型别名

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

类型别名扩展接口

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

4.工具

类可以以相同的方式实现接口或类型别名。但是请注意,类和接口被视为静态蓝图。因此,它们不能实现/扩展命名联合类型的类型别名。

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.申报合并

与类型别名不同,接口可以定义多次,并将被视为单个接口(合并所有声明的成员)。

// 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 };

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

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

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