在TypeScript中为什么应该使用Type而不是Interface

在TypeScript中经常会遇到应该使用Type还是Interface的问题,本篇文章将讲解应该使用Type而不是Interface的好处

以下是最常见的使用场景,可以看到TypeInterface都能用作组件属性类型

typescript 复制代码
type UserProps = {
  name: string;
  age: number;
}
   
// interface UserProps {
//   name: string;
//   age: number;
// }
   
export default function User({}: UserProps){
  return <div>Card</div>;
}

给一个基础类型增加其他属性

type使用的是交叉

typescript 复制代码
type UserProps = {
  name: string;
  ages: number;
};

type AdminProps = UserProps & {
  role: string;
}

interface使用的是继承

typescript 复制代码
interface UserProps {
  name: string;
  age: number;
}

interface AdminProps extends UserProps {
  role: string;
}

interface只能描述对象,而type可以描述对象以及其他任何东西(例如:像string,number,boolean等原生类型)

为了更语义化,定义一个Address类型,这个类型实际是string类型

typescript 复制代码
type Address = string;

const address: Address = "广东省深圳市南山区";

interface为了实现这种效果,需要这样使用

typescript 复制代码
interface Address {
  address: string;
}

const address: Address = {
  address: "广东省深圳市南山区"
}

可以看出使用type更加方便

type可以描述联合类型,而interface不行

typescript 复制代码
type Address = string | string[];

const address: Address = ["广东省深圳市南山区", "广东省深圳市福田区"]

type可以轻松使用工具类型,interface也可以,不过只能用丑陋的语法

使用Omit取出UserProps中除某几个属性外的其他属性作为一个新的类型

typescript 复制代码
type UserProps = {
  name: string;
  age: number;
  createdBy: Date;
}

type GuestProps = Omit<UserProps, "name" | "age">;

interface需要使用继承,并会有一个空的括号

typescript 复制代码
interface GuestProps extends Omit<UserProps, "name" | "age"> {}

type可以轻松描述元组,interface也可以,不过只能用丑陋的语法

typescript 复制代码
type Address = [number, string];

// interface Address extends Array<number | string> {
//   0: number;
//   1: string;
// }

const address: Address = [1, '广东省深圳市南山区'];

从其他类型提取类型

typescript 复制代码
const project = {
  title: "Project 1",
  specification: {
    areaSize: 100,
    rooms: 3
  },
}

// const project = {
//   title: "Project 1",
//   specification: {
//     areaSize: 100,
//     rooms: 3
//   },
// } as const

type Specification = typeof project["specification"];

甚至可以给project加上as const,这样specification中的areaSizerooms都固定为常量了

interface可以被合并,"interface是开放的"和"type是收敛的"

typescript 复制代码
interface User {
  name: string;
  age: number;
}

interface User {
  role: string;
}

let user: User = {
}

两个Userinterface可以同时定义,最终User将会是两者的结合,这在使用第三方库并存在相同interface的时候会造成困扰

typescript 复制代码
type User = {
  name: string;
  age: number;
}

// type User = {
//   role: string;
// }

type User2 = User & {
  role: string;
}

let user: User2 = {
  
}

定义两个相同名称的User将会报错,可以使用交叉类型来增加属性,清晰明了

type也能被class使用

typescript 复制代码
interface IUser {
  name: string;
  age: number;
}

type TUser = {
  name: string;
  age: number;
}

class User implements TUser {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

结语

当我们能用type实现interface的所有功能,并且方式更优雅,而且还具备interface不能实现的功能时,我们应该毫不犹豫选择使用type而不是interface,毕竟我们用的是TypeScript而不是InterfaceScript

相关推荐
拜晨几秒前
使用motion实现小宇宙节目广场的效果
前端·交互设计
爱吃甜品的糯米团子24 分钟前
详解 JavaScript 内置对象与包装类型:方法、案例与实战
java·开发语言·javascript
知花实央l26 分钟前
【Web应用实战】 文件上传漏洞实战:Low/Medium/High三级绕过(一句话木马拿webshell全流程)
前端·学习·网络安全·安全架构
华仔啊26 分钟前
JavaScript + Web Audio API 打造炫酷音乐可视化效果,让你的网页跟随音乐跳起来
前端·javascript
鸡吃丸子29 分钟前
SEO入门
前端
檀越剑指大厂1 小时前
【Nginx系列】Tengine:基于 Nginx 的高性能 Web 服务器与反向代理服务器
服务器·前端·nginx
是你的小橘呀1 小时前
深入理解 JavaScript 预编译:从原理到实践
前端·javascript
uhakadotcom1 小时前
在使用cloudflare workers时,假如有几十个请求,如何去控制并发?
前端·面试·架构
风止何安啊1 小时前
栈与堆的精妙舞剧:JavaScript 数据类型深度解析
前端·javascript
用户47949283569151 小时前
Chrome DevTools MCP:让 AI 助手直接操作浏览器开发工具
前端·javascript·chrome