初入TS坑之interface和type的区别

89 阅读3分钟

两者的概念

interface用于定义一个对象的类型,也是可用于以后的类型定义

interface Person {
  name:string;
  age:number
}
// 在使用的时候不能多属性也不能少属性
const tom:Person = {
  name:"Tom",
  age:20
}

如果定义了属性,赋值的时候必须做到与定义的属性完全一致,如果需要不完全匹配可以使用可选属性

interface Person {
  name:string;
  // 表示可选属性,可以有也可以没有
  age?:number;
}
const tom:Person = {
  name:"Tom"
}

使用了可选属性还是不能添加未定义的属性,如果想要添加未定义的属性可以使用任意属性

interface Person {
  name:string;
  // 可选属性
  age?:number;
  // 任意属性,下面表示key必须是string类型,值可以是任意类型
  [key:string]:any
}

在任意属性中,[key: string]中的key是一个变量名,所以可以使用你喜欢的任意名,如[propName:string]也是可以的

特别注意:如果定义了任意属性,那么确定属性和可选属性的类型都必须是任意属性类型的子类型,下面举例说明

interface Person {
  name:string;
  age?:number;
  // 这样写是会报错的;因为age是需要number类型,这样写定义了Person接口里面只能有string类型
  [key:string]:string
}

定义只读类型

interface Person {
  readonly name:string;
  age?:number
}
const tom:Person = {
  name: "Tom",
  age: 20
}
tom.age = 18;
// 这句代码就会报错,因为name是只读
tom.name = "Tom1";

type是给一个类型或者对象类型取个名字,在以后的类型定义中可以使用,包括原始值、联合类型等中可以使用

// 定义一个名叫Name的类型,之后使用Name就表示限制为string类型
type Name = string;
// 这里使用Name限制传入的参数n是一个字符串类型
function getName(n: Name){
  return n;
}
// 也可以使用type定义对象类型
type Person = {
  name:string,
  age:number
}

如果type定义了对象类型,赋值的对象必须做到对象类型中的确定类型必须全部有,可选类型可以有可以没有;type不需要定义任意类型,我们可以在赋值对象中任意添加

type Person = {
  readonly name:string;
  age?:number;
}
function getPerson(person: Person){
  // 这么做是不允许的,因为name为只读属性
  person.name = "Tom1";
  console.log(person)
  return `我的名字叫${person.name},今年${person.age}岁`;
}
const person = {
  name: "Tom",
  age: 20,
  // 这个属性是允许增加的
  gender:"male"
}
console.log(getPerson(person))

两者的相同点

  1. 都可以做为对象接口使用
  2. 都可以在原有基础上做扩展,也可以相互继承;但是扩展方式不同
interface Person {
  name:string;
  age:number
}
// 科学家继承了人的特点,也扩展了自己的特点
interface Scientist extends Person {
  speciality:string
}
const tom: Scientist = {
  name:"Tom",
  age:20,
  speciality:"专注"
}
console.log(tom)

// 将上述内容使用type完成
type Person = {
  name:string;
  age:number
}
type Scientist = Person & {
  speciality:string
}
const tom: Scientist = {
  name:"Tom",
  age:20,
  speciality:"专注"
}
console.log(tom)

两者的区别

  1. 上面的使用方法中说了一种区别,在任意类型的定义上,interface是需要定义任意类型的,但是type不要定义
  2. type可以定义基本类型,但是interface只能定义对象类型
  3. interface可以重复定义,如果重复定义同一属性他们的类型必须相同,不然会报错
interface Person {
  name: string;
}
interface Person {
  age: number;
}
// name和age属性都必须要定义,否则会报错
const tom:Person = {
  name: "Tom",
  age: 20
}