typescript(ts) interface 与 type 的异同

简介: 接口可以使用 extends 关键字来进行扩展(这个继承是包含关系,如果父级有了,子集不可以声明重复的,会报错的),或者是 implements来进行实现某个接口

看到网上已经有好多人介绍这两者的区别,本人是恰好学到这里,然后做点自己的学习笔记,给后面学习的小伙伴留下点足迹.话不多说,往下看。


不同点


语法上


type 和 interface 的语法不一样,type 需要等号,而 interface 不需要等号


// interface 声明的类型检查
interface User {
  name: String
  age: number
  sayHello: () => void
  sayHi(): void
}
// 类型别名声明的类型检查
type UserType = {
  name: String
  age: number
  sayHello: () => void
  sayHi(): void
}


定义的类型上


  • 接口主要声明的是函数和对象,并且总是需要引入特定的类型
  • 类型别名声明的可以是任何的数据类型(基本类型别名,联合类型,元组等类型)


// 接口声明的类型检查
// 定义一个对象
interface Point {
  x: number;
  y: number;
}
// 定义一个函数
interface SetPoint {
  (x: number, y: number): void; // 或者 (x:number, y:number): () => void
}
// 类型别名定义的类型检查,例如
type Point = {
    x: number;
    y: number;
};
type SetPoint = (x: number, y: number) => void;
// 定义原生类型
type Name = string;
// 对象
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };
// 联合类型
type PartialPoint = PartialPointX | PartialPointY;
// 元组
type Data = [number, string];
...


扩展的方式不一样


  • 接口可以使用 extends 关键字来进行扩展(这个继承是包含关系,如果父级有了,子集不可以声明重复的,会报错的),或者是 implements来进行实现某个接口


20210113161223736.png


  • 类型别名也可以进行扩展,使用 &符号进行(这个继承是合并关系,如果父级有了一个类型,子集还可以声明,但是类型就是变成 &;)这个叫做交叉类型


20210113162126896.png


注意,虽然说 类型别名可以 这样父级和子级声明相同的类型,但是在类型检查会类型推导成其他的,这样使用可能会导致定义的类型与预期不符合


合并声明


  • 接口可以定义一个名字,后面的接口也可以直接使用这个名字,自动合并所有的声明,可以理解类似为继承,但是不建议这么使用,还是使用extends关键字好


// interface能够声明合并
interface User {
  T1: string
}
interface User {
  T2: number
}
/*
User 接口为 {
  T1: string
  T2: number
}
*/


20210113163241244.png


  • 类型别名不能这么使用,会直接报错


20210113163415193.png


实例类型进行赋值


  • 接口 没有这个功能
  • 类型别名 可以使用 typeof 获取实例的 类型进行赋值(下面的代码在浏览器环境下)


let div = document.createElement('div');
type B = typeof div


类型映射


  • 接口 没有这个功能
  • 类型别名 可以通过 in来实现类型映射,如下:


type Keys = "firstname" | "lastname"
type DudeType = {
  [key in Keys]: string
}
const test: DudeType = {
  firstname: "323",
  lastname: "332"
}


20210113164858279.png


最大的不同


接口可以被类实现,而类型别名不可以

接口是用来表达某个类是否拥有某种能力的,其实这就是实现了接口


我们有一个这样的场景,学生都会学会许多的技能,技能可以从没有,然后到有,然后再到没有。这个怎么来设计类。


这里我们可以进行分析,我们可以设计好多个基类,每一个基类分别代表不同的技能,然后在进行继承,但是大家似乎忘记了,类的继承是单继承,不能多继承哦?类的继承,但是我们怎么来实现上面的场景呢? 使用接口, 理论上一个类可以实现n 个接口


interface ISing {
  sing:() => void;
}
interface IDance{
  dance: () =>void
}
class littleStudent implements ISing, IDance{
// 这里必须实现接口的方法,是强约束力的。
  sing(){
  };
  dance(): void{
  }
}


20210125155803101.png


接口可以继承类,类型别名不行


接口可以多继承类,表示该类的所有成员都在接口中。如下


20210125160052194.png


相同点


两者都不会出现在编译结果里面


// 接口声明的类型检查
interface User{
  name: String
  age: number
  sayHello: () => void
  sayHi(): void
}
// 类型别名声明的类型检查
type UserType = {
  name: String
  age: number
  sayHello: () => void
  sayHi(): void
}
const user: User = {
  name: 'test',
  age: 12,
  sayHello: () => {
  },
  sayHi: () => {
  }
}


编译对比结果如下:


20210113165515913.png


两者都可以进行扩展


只是拓展的方式不一样而已,具体查看上面的拓展


// interface extends interface
interface Name { 
  name: string;  
}
interface User extends Name { 
  age: number; 
}
// type extends type
type Name = {
  name: string
}
type User = Name & { age: number }
// interface extends type
interface User extends Name
// type extends interface
interface Name {
  name: string
}
type user = Name & {
  age: number
}


描述函数和对象


// interface
interface User {
  name: string
  age: number
  (name: string, age; number): void
}
// type
type User = {
  name: string
  age: number
}
type setProps = (name: string, age: number) => void 


总结


一般来说,如果不清楚什么时候用interface/type,能用 interface 实现,就用 interface , 如果不能就用 type 。其他更多详情参看 官方规范文档

相关文章
|
3月前
|
JavaScript
typeScript进阶(9)_type类型别名
本文介绍了TypeScript中类型别名的概念和用法。类型别名使用`type`关键字定义,可以为现有类型起一个新的名字,使代码更加清晰易懂。文章通过具体示例展示了如何定义类型别名以及如何在函数中使用类型别名。
47 1
typeScript进阶(9)_type类型别名
|
3月前
|
JavaScript
typeScript基础(3)_ts函数默认值和可选参数
本文介绍了在TypeScript中如何使用函数的默认值和可选参数。展示了如何为函数参数指定默认值,使得在调用函数时可以省略某些参数,以及如何定义可选参数。
203 2
|
5月前
|
JavaScript 前端开发 开发工具
TypeScript的介绍,let age:number = xxx,可以直接看出数据类型,Type由微软开发,可以在任何浏览器和系统中运行,比较适合大型项目,TypeScript的安装
TypeScript的介绍,let age:number = xxx,可以直接看出数据类型,Type由微软开发,可以在任何浏览器和系统中运行,比较适合大型项目,TypeScript的安装
|
3月前
|
JavaScript 前端开发
typeScript基础(8)_ts类型断言
本文介绍了TypeScript中的类型断言,它用于在编译时告诉TypeScript某个对象具有特定的类型,即使它看起来不具备。类型断言可以用来访问一个类型上存在而另一个类型上不存在的属性或方法。需要注意的是,类型断言并不会在运行时改变JavaScript的行为,因此如果断言不当,运行时仍然可能出错。文章还提醒避免将类型断言为`any`类型或进行多重断言。
41 1
|
2月前
|
JavaScript 索引
TypeScript(TS)安装指南与基础教程学习全攻略(二)
TypeScript(TS)安装指南与基础教程学习全攻略(二)
59 0
|
2月前
|
JavaScript 前端开发 安全
TypeScript(TS)安装指南与基础教程学习全攻略(一)
TypeScript(TS)安装指南与基础教程学习全攻略(一)
31 0
|
6月前
|
JavaScript 索引 前端开发
9.【TypeScript 教程】接口(Interface)
9.【TypeScript 教程】接口(Interface)
64 4
|
6月前
|
JavaScript 安全 前端开发
TypeScript 基础学习笔记:interface 与 type 的异同
TypeScript 基础学习笔记:interface 与 type 的异同
70 0
|
7月前
|
JavaScript
【TS】You are currently running a version of TypeScript which is not officially supported by @typesc
【TS】You are currently running a version of TypeScript which is not officially supported by @typesc
242 2
|
7月前
|
JavaScript 前端开发 开发者
JavaScript与TypeScript:深入解析两者之间的异同
【4月更文挑战第23天】本文对比分析了JavaScript和TypeScript的异同。作为JavaScript超集,TypeScript添加了静态类型和类等特性,有助于提升代码质量和可维护性。两者在语法上相似,都能在浏览器或Node.js环境中运行。JavaScript适合小项目和快速开发,而TypeScript适用于大型项目,因其静态类型和强大的生态系统能减少错误并便于团队协作。理解两者差异有助于开发人员根据项目需求作出合适选择。