相同点

  1. interface IAnimal {
  2. name: string;
  3. }
  4. type Animal = {
  5. name: string;
  6. };

泛型 Generics

interface IAnimal<p = string> {
  name: p;
}

type Animal<p = string> = {
  name: p;
};

交叉继承 Intersections

type Robot = {
  power: number;
};

interface IRobot {
  name: string;
}

interface IRobotAnimal1 extends IAnimal, IRobot {}
interface IRobotAnimal2 extends IAnimal, Robot {}
interface IRobotAnimal3 extends Animal, IRobot {}
interface IRobotAnimal4 extends Animal, Robot {}

type RobotAnimal1 = IAnimal & IRobot;
type RobotAnimal2 = IAnimal & Robot;
type RobotAnimal3 = Animal & IRobot;
type RobotAnimal4 = Animal & Robot;

实现 Implements

class Dog implements IAnimal {
  name: string = 'doge';
}

class Cat implements Animal {
  name: string = 'cat cat';
}

继承类 Extend classes

class Control {
  private state: any;
}

interface ISelectableControl extends Control {
  select(): void;
}

type SelectableControl = Control & {
  select(): () => void;
};

函数 Functions

type Bark = (x: string) => void;

interface IBark {
  (x: string): void;
}

// 函数 泛型
type Bark1 = <T = Animal>(x: T) => void;

interface IBark1 {
  <T = Animal>(x: T): void;
}

递归声明 Recursive declarations

type Tree<P> = {
  node: P;
  leafs: Tree<P>[];
};

interface ITree<P> {
  node: P;
  leafs: Tree<P>[];
}

精确校验 Exact

type Close = { a: string };
const x: Close = { a: 'a', b: 'b', c: 'c' };
// Type '{ a: string; b: string; c: string; }' is not assignable to type 'Close'.
// Object literal may only specify known properties, and 'b' does not exist in type 'Close'.

interface IClose {
  a: string;
}
const y: IClose = { a: 'a', b: 'b', c: 'c' };
// Type '{ a: string; b: string; c: string; }' is not assignable to type 'IClose'.
// Object literal may only specify known properties, and 'b' does not exist in type 'IClose'.

可索引的 Indexable

type StringRecord = {
  [index: string]: number;
};

interface IStringRecord {
  [index: string]: number;
}

不同点

只能使用 type 来别名基本类型

type NewNumber = number;

interface INewNumber extends number {}
// 'number' only refers to a type, but is being used as a value here.

interface INewNumber extends Number {}
// 这样写是可以的,但是不要忘记 1 instanceof Number === false

元组 Tuples

不能使用 interface 声明元组

type Tuples = [number, number];

interface ITuples {
  0: number;
  1: number;
}

[1, 2, 3] as Tuples;
// Conversion of type '[number, number, number]' to type 'Tuples' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Types of property 'length' are incompatible.

[1, 2, 3] as ITuples;

不相关的合集 Disjoint unions

只有 type 可以做不相关合集

type SomeAnimal = { type: Dog } | { type: Cat };

且不能对 不相关集合不能使用 extends 关键字

interface ISomeAnimal extends SomeAnimal {}
// An interface can only extend an object type or intersection of object types with statically known members

new

你可以声明 new 的类型

interface IClassyAnimal {
  new (name: string);
}
// Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.

上述写法并不能满足需求

class Parrot implements IClassyAnimal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}
// Class 'Parrot' incorrectly implements interface 'IClassyAnimal'.
//  Type 'Parrot' provides no match for the signature 'new (name: string): any'.

通过修改 constructor 也不可以

interface IClassyAnimal {
  constructor(name: string): void;
}

class Parrot implements IClassyAnimal {
  name: string;
  constructor(name: string) {
    this.name = name
  }
}
// Class 'Parrot' incorrectly implements interface 'IClassyAnimal'.
//  Types of property 'constructor' are incompatible.
//    Type 'Function' is not assignable to type '(name: string) => void'.
//      Type 'Function' provides no match for the signature '(name: string): void'.

每个作用域仅一个声明

每个作用域只能声明一次类型

type Once = { a: string };
type Once = { b: string };
// Duplicate identifier 'Once'.

可以在每个作用域中多次声明接口(最终结果将是所有声明的总和)

interface IOnce {
  a: string;
}
interface IOnce {
  b: string;
}

http://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases https://dev.to/stereobooster/typescript-type-vs-interface-2n0c