在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

相关推荐
ZC跨境爬虫11 小时前
跟着 MDN 学CSS day_9:(深入掌握CSS选择器核心技能测试)
前端·css·ui·html
Daybreak11 小时前
Convex + Next.js + Clerk 上线求生指南:六个坑,一个比一个离谱
前端
marsh020611 小时前
53 openclaw插件市场:开发与发布自己的插件
开发语言·前端·javascript
Daybreak11 小时前
AI Chat 重构:从全屏页面到右侧可折叠侧边栏,7 个 Zustand Store 合并为 1 个 Hook
前端
Daybreak11 小时前
从硬编码路由到 ReAct Agent Loop:AI Chat 的工具调用重构
前端
用户9385156350711 小时前
全栈小项目实战:从零搭建用户列表
javascript
用户329104422504111 小时前
基于 Claude Code 实现 CI/CD 完整流程
前端·后端
星栈11 小时前
别让 API 跳去登录页:我在 Axum 里做了认证失败双通道
前端·后端·开源
Cache技术分享11 小时前
416. 现代 Java I/O 最佳实践 - 高效、简洁、安全地处理文本与数据
前端·后端
前端繁华如梦11 小时前
three.js从盒子到链条的程序化三维实现
前端·javascript