在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

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师1 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端