说到typeinterface,很多时候很多人都是用的很随意,因为有时候可以用 type,也可以用interface。那到底什么时候 type,什么时候用 interface呢?

要搞明白这个问题,就显得搞明白这两者各自的特点

interface

interface我们叫他接口ts设计出来主要用于定义对象类型,可以对对象类型进行描述。比方说,我们现在要对一个对象的类型进行约束,你可以这样来

let obj: { age: number; name: string } = {age: 28, name: "constRen"}

这样写的话,树形多的时候,可能就不是很美妙了,还有就是,每写一个对象,都要去写一下类型,很麻烦。作为一个程序员,这能忍?

所以,接口就应运而生

interface User {
  name: string;
  age: number;
  sex: string;
  hobby?: string;
}

let obj1: User = {
  name: '张三',
  age: 28,
  sex: '男',
  hobby: '打篮球'
}

let obj2: User = {
  name: '李四',
  age: 28,
  sex: '男',
}

interface addTp {
  (num1: number, num2: number): number;
}

const add: addTp = (num1, num2) => {
  return num1 + num2
}

这就是接口的简单用法

type

type就是一个类型别名,说白了就是一个小名,绰号...我不相信有人每次称呼乔丹都是迈克尔乔丹,我们一般都是称之为乔丹,这就是别名,把科比布莱恩特称之为科比,把勒布朗詹姆斯称之为詹姆斯,把扬尼斯·西纳·乌戈·阿德托昆博称之为字母哥...这就是别名。他只是给类型起一个新名字(随便自定义一个类型,使用type给他一个名字就行,加上type的写法就是一个表达式,所以注定它用途广泛)

type Person = {
  name: string
  age: number
}
const my: Person = {
  name: 'climblee',
  age: 18
}
type addTp = (a: number, b: number) => number
const add: addTp = (a, b) => {
  return a + b
}
type Name = string
const name: Name = 'climblee'

这就是type的简单用法

两者相同点

  • 都能定义函数和对象(见上面的代码)

  • 都能继承(扩展)

    • interface的继承

      // interface 继承 interface
      interface Person {
        name: string
      }
      
      interface Student extends Person {
        age: number
      }
      
      let my: Student = {
        name: '张三',
        age: 18
      }
      
    • type的继承

      // type 继承 type
      type Person =  {
        name: string
      }
      
      type Student = Person & {
        age: number
      }
      
      let my: Student = {
        name: '张三',
        age: 18
      }
      
      // type 继承 interface
      interface Person {
        name: string
      }
      
      type Student = Person & {
        age: number
      }
      
      let my: Student = {
        name: '张三',
        age: 18
      }
      

两者不同点

type可以,interface不行的

type会给一个类型起一个新名字,有时和 interface很像,但是 type可以作用于原始值,联合类型,元组以及其他任何你需要手写的类型

  • 声明基本类型、元组

    type aaa = String;
    
    const name:aaa = "wanna"
    
  • keyof、in、Pick、Omit、Exclude、Extract......这些只有type可以

    interface InterfaceA {
      key1: string;
    }
    
    interface InterfaceB {
      key2: number;
    }
    
    type UnionType = InterfaceA | InterfaceB;
    type IntersectionType = InterfaceA & InterfaceB;
    
    const obj1: UnionType = { key1: 'hello' }; // 符合 InterfaceA
    const obj2: UnionType = { key2: 42 }; // 符合 InterfaceB
    const obj: IntersectionType = { key1: 'hello', key2: 42 }; // 同时符合 InterfaceA 和 InterfaceB
    
  • 就不一一举例了,那些ts的中高级以及交叉类型,基本都是使用 type

interface可以,type不行的

  • 合并重复声明:interface重复声明就会合并,type不支持,会给你报个错

    interface A {
      name: string;
    }
    
    interface A {
      age: number;
    }
    
    // A 接口被合并为 { name: string; age: number; }
    const a: A = {
      name: 'Jack',
      age: 20
    }
    
    // Error: Duplicate identifier 'B'.
    type B = {
      name: string;
    }
    
    type B = {
      age: number;
    }
    
  • 从这个例子可以看到,本身 Person里面只有一个name属性,没有 age属性,但是重复声明后就会合并,就有了 nameage两个属性,在没有加可选的情况下,少了这个属性就会报错。我们再来看 type的重复声明

  • interface 可以被类实现和扩展,而 type 不行

    interface Animal {
      name: string;
      eat(): void;
    }
    
    type Animal2 {
      name: string;
      eat(): void;
    }
    
    class Cat implements Animal {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
      eat() {
        console.log(`${this.name} is eating.`);
      }
    }
    // 错啦,type定义的对象类型不能被实现
    class Dog implements Animal2 {
      name: string;
      constructor(name: string) {
        this.name = name;
      }
      eat() {
        console.log(`${this.name} is eating.`);
      }
    }