在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跨境爬虫6 小时前
跟着 MDN 学 HTML day_9:(信件语义标记)
前端·css·笔记·ui·html
前端老石人6 小时前
HTML 字符引用完全指南
开发语言·前端·html
matlab_xiaowang6 小时前
Redux 入门:JavaScript 可预测状态管理库
开发语言·javascript·其他·ecmascript
幼儿园技术家6 小时前
前端如何设计权限系统(RBAC / ABAC)?
前端
前端摸鱼匠8 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker8 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
donecoding10 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马10 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren10 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川10 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端