TypeScript: Interfaces vs Types — 2024年该如何选择?

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:TypeScript开发者永恒的争论



如果您曾使用TypeScript编写过代码,那么您很可能遇到过这个问题:“什么时候使用interface,什么时候使用type?”这个问题在Stack Overflow上获得了数千次浏览,并成为初学者的真正绊脚石。让我们一劳永逸地解决这个难题。



TypeScript是JavaScript的超集,它添加了静态类型系统。我们有两个主要工具来描述数据结构:Interface和Type Alias。乍一看,它们做的是同一件事,但魔鬼藏在细节中。在本文中,我们不仅会列出差异——还会通过实际示例展示它们,并给出明确的建议。



什么是Interface?



Interface是一种描述对象结构的方式。它就像数据的蓝图:您告诉TypeScript对象应该具有哪些属性和方法。



// 基本接口interface User {    name: string;    age: number;    email?: string; // 可选属性    readonly id: number; // 只读属性}

// 使用const user: User = { name: "安娜", age: 25, id: 1};


接口可以相互继承,这使得它们非常适合描述层级结构:



interface Animal {    name: string;    sound(): void;}

interface Dog extends Animal { breed: string; wagTail(): void;}

// 现在Dog包含Animal的所有字段以及自己的字段const myDog: Dog = { name: "雷克斯", breed: "德国牧羊犬", sound() { console.log("汪!"); }, wagTail() { console.log("摇尾巴"); }};


什么是Type Alias?



Type Alias(类型别名)是一种更灵活的工具。它不仅可以描述对象,还可以描述原始类型、联合类型和交叉类型。



// 原始类型的类型别名type ID = string | number;

// 对象的类型别名type UserType = { name: string; age: number;};

// 函数的类型别名type Greeting = (name: string) => string;

// 联合类型type Status = "active" | "inactive" | "pending";

// 交叉类型type Person = { name: string };type Employee = Person & { salary: number };


类型的主要超能力是联合类型。接口无法做到这一点:



// ❌ 接口不能这样使用// interface Status = "active" | "inactive"; // 错误!

// ✅ 而类型别名可以轻松做到!type Status = "active" | "inactive" | "pending";

function processStatus(status: Status) { switch (status) { case "active": console.log("活跃"); break; case "inactive": console.log("不活跃"); break; case "pending": console.log("待处理"); break; }}


关键区别:Interface vs Type



让我们详细分析一下它们在实际使用中的区别。



1. 联合类型与交叉类型

Type直接支持联合类型(|)和交叉类型(&)。Interface只能通过extends实现。



// 联合类型——仅type支持type Success = { data: string };type Error = { error: string };type Result = Success | Error; // 可行!

// 交叉类型type Full = Success & Error; // 可行!

// 对于interface,需要创建单独的接口interface IResult extends Success, Error {} // 可行,但比较繁琐


2. 声明合并

这是接口的独特功能。如果您声明两个同名的接口,TypeScript会将它们合并。



// 第一个接口interface User {    name: string;}

// 第二个同名接口interface User { age: number;}

// 结果:User = { name: string; age: number; }const user: User = {

博客

书籍推荐