- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
导读
在 TypeScript 中,interface(接口)与type(类型别名)是描述对象结构的两大核心工具。本文基于《The Concise TypeScript Book》中 interface-and-type 章节,系统讲解接口与类型的通用语法、类型定义的常见形态(基本类型、对象、联合、交集),并结合同仓库的差异对比、合并扩展等章节,深入剖析二者在声明合并、继承扩展、复杂类型表达上的关键区别。读完本文,你将掌握如何在日常开发中为对象、函数与组合类型写出清晰、可维护的类型定义,并能根据具体场景正确选择interface或type。
接口与类型的通用语法
在 TypeScript 中,接口用于定义对象的结构,明确指定一个对象必须拥有的属性名称、类型以及方法签名。定义接口的通用语法如下:
interface InterfaceName { property1: Type1; // ... method1(arg1: ArgType1, arg2: ArgType2): ReturnType; // ... }类型别名的定义方式与之相似,只是使用type关键字并配合赋值语法:
type TypeName = { property1: Type1; // ... method1(arg1: ArgType1, arg2: ArgType2): ReturnType; // ... };对语法中的每个部分逐项拆解:
interface InterfaceName或type TypeName:定义接口或类型的名称。接口通过声明块组织成员;类型别名则通过=将右侧的对象字面量类型赋给左侧名称。property1: Type1:指定接口的属性及其对应的类型。可以定义多个属性,每个属性之间用分号分隔。method1(arg1: ArgType1, arg2: ArgType2): ReturnType;:指定接口的方法。方法由名称、括号内的参数列表(每个参数标注类型)以及返回值类型组成。同样可以定义多个方法,彼此用分号分隔。
一个完整的接口示例:
interface Person { name: string; age: number; greet(): void; }与之等价的形式,用类型别名书写:
type TypeName = { property1: string; method1(arg1: string, arg2: string): string; };在 TypeScript 中,类型(types)用于定义数据的形态并强制执行类型检查。根据具体的使用场景,有若干常见的类型定义语法,下面逐一展开。
类型定义的各种形态
基本类型(Tipos Básicos)
基本类型注解直接写在变量声明之后,适用于数字、布尔、数组、元组等场景:
let myNumber: number = 123; // number 类型 let myBoolean: boolean = true; // boolean 类型 let myArray: string[] = ['a', 'b']; // 字符串数组 let myTuple: [string, number] = ['a', 123]; // 元组(tuple)值得注意的是,TypeScript 在推断简单类型时表现很好,正如 type-annotations 章节 所指出的,这类简单注解在大多数情况下并非必需,更多是用于明确意图或约束边界。该章节还给出了一套实用建议:优先为函数的参数与返回值标注类型签名,但不必为函数体内的局部变量逐一注解;对对象字面量则始终建议显式给出类型。
对象与接口(Objetos e Interfaces)
对象形态的类型既可以通过内联对象字面量语法直接书写,也可以通过interface或type命名:
const x: { name: string; age: number } = { name: 'Simon', age: 7 };关于对象类型的两种主要定义方式,object-types 章节 做了进一步说明:
- interface:定义对象的形状,指定属性名称、类型及其可选性。
- type alias:与 interface 类似,定义对象的形状;但它还能基于现有类型或现有类型的组合创建全新的自定义类型,包括联合类型、交集类型等复杂类型。
interface User { name: string; age: number; email?: string; } type Point = { x: number; y: number; };对象类型也可以匿名定义,直接在函数参数处内联:
const sum = (x: { a: number; b: number }) => x.a + x.b; console.log(sum({ a: 5, b: 1 }));若对象中的某些属性可有可无,可以在属性名后加问号?将其标记为可选。如 optional-properties 章节 所示,可选属性还可以配合解构默认值使用:
type X = { a: number; b?: number; // 可选 }; const x = ({ a, b = 100 }: X) => a + b;联合类型与交集类型(Tipos União e Interseção)
联合类型(Union Type)表示一个值可以是若干类型中的任意一种,用符号|连接每种可能的类型。关于联合类型的完整定义可参考 union-type 章节:
type MyType = string | number; // 联合类型 let myUnion: MyType = 'hello'; // 可以是字符串 myUnion = 123; // 也可以是数字交集类型(Intersection Type)表示一个值同时拥有两个或多个类型的全部属性,用符号&连接,参见 intersection-types 章节:
type TypeA = { name: string }; type TypeB = { age: number }; type CombinedType = TypeA & TypeB; // 交集类型 let myCombined: CombinedType = { name: 'John', age: 25 }; // 同时具有 name 和 age 属性的对象Interface 与 Type 的关键差异
虽然接口与类型别名在定义对象结构时功能高度重叠,但二者在以下三个维度上存在本质差异,详见 differences-between-type-and-interface 章节。
差异一:声明合并(Mesclagem de declarações)
接口支持声明合并:你可以用同一个名字定义多个接口,TypeScript 会自动将它们合并为包含全部属性与方法的单一接口。类型别名则不支持声明合并。这一特性在「不修改原始定义、为现有类型补充额外功能或修正缺失/错误类型」的场景下非常有用:
interface A { x: string; } interface A { y: string; } const j: A = { x: 'xx', y: 'yy', };合并与扩展是处理类型时两个截然不同的概念,merging-and-extension 章节 对此有专门论述:合并(merging)允许你把多个同名声明组合成单一定义;扩展(extension)则允许从已有类型或接口继承以创建新类型,无需改动原始定义即可追加属性或方法。实际开发中,声明合并常被用于为第三方库的类型打补丁(如为全局对象扩展方法),或为配置文件、环境变量等模块增强类型。
差异二:扩展其他类型/接口(Estendendo outros tipos/interfaces)
类型与接口都可以扩展其他类型或接口,但语法不同:
- 接口使用
extends关键字继承其他接口的属性与方法,但接口不能直接扩展复杂类型(如联合类型):
interface A { x: string; y: number; } interface B extends A { z: string; } const car: B = { x: 'x', y: 123, z: 'z', };- 类型使用
&操作符把多个类型组合成单个类型(交集):
interface A { x: string; y: number; } type B = A & { j: string; }; const c: B = { x: 'x', y: 123, j: 'j', };关于扩展的方向性,extending-types 章节 给出了三条关键规则:
- 可以扩展单个接口,也可以一次从多个类型扩展(多继承):
interface X { a: string; } interface Y extends X { b: string; } interface A { a: string; } interface B { b: string; } interface Y2 extends A, B { y: string; }extends关键字只适用于接口和类;对类型别名,请使用交集:
type A = { a: number; }; type B = { b: number; }; type C = A & B;- 可以用接口扩展一个类型别名,但反过来不行——类型别名无法用
extends扩展接口:
type A = { a: string; }; interface B extends A { b: string; }差异三:联合类型与交集类型的表达能力(Tipos União e Interseção)
类型别名在定义联合与交集类型时更加灵活:用|可以轻松创建联合类型,用&可以创建交集类型。接口虽然也能间接表达联合类型,但不具备内建的交集类型支持。因此,凡是涉及组合类型的场景,都应使用type:
type Department = 'dep-x' | 'dep-y'; // 联合类型 type Person = { name: string; age: number; }; type Employee = { id: number; department: Department; }; type EmployeeInfo = Person & Employee; // 交集类型接口表达联合类型的一种方式是「间接实现」——先定义多个接口,再用类型别名把它们组合成联合:
interface A { x: 'x'; } interface B { y: 'y'; } type C = A | B; // 接口的联合但请注意,这里的C只能以type形式存在;interface C = A | B在语法上是不合法的。
如何选择:interface 还是 type?
综合上述差异,可以归纳出面向实战的选型建议:
- 需要声明合并 / 扩展现有类型(如为全局或第三方类型打补丁)时,优先使用
interface。它是 TypeScript 为「结构化类型契约」设计的原生产物,extends单继承、多继承语义清晰。 - 需要表达联合类型、交集类型、映射类型、条件类型或元组等组合形态时,只能使用
type。这也是 differences-between-type-and-interface 章节 反复强调的结论:类型别名在组合类型上拥有接口不具备的表达力。 - 单纯描述一个对象/函数的形状时,二者皆可。此时选择标准主要取决于团队约定与扩展预期:若未来可能通过合并来增强,选
interface;若更看重组合能力与一致性,选type。正如 type-annotations 章节 的建议——对对象字面量始终显式添加类型,能让联合/交集组合的对象形态更易读、更可维护。
在本书中继续深入
本文内容是《The Concise TypeScript Book》类型体系章节的组成部分。若想进一步巩固,建议沿着以下仓库路径继续阅读:
- interface-and-type.md(英文原版):接口与类型的通用语法基准;
- differences-between-type-and-interface.md:差异三要素的权威对比;
- union-type.md 与 intersection-types.md:联合、交集类型的精确定义;
- extending-types.md 与 merging-and-extension.md:扩展与合并的完整规则;
- object-types.md、optional-properties.md、type-annotations.md:对象形态、可选属性与注解风格的最佳实践。
这些章节与本仓库其他类型主题(如 type-from-value、type-manipulation、mapped-types 等)共同构成一套由浅入深的 TypeScript 类型学习路径,可作为团队内训或自学的参考资料。
- 文档
- 教程
【免费下载链接】typescript-book
The Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.
相关推荐
TypeScript 的 Interface 与 Type 类型定义详解:语法、实战与选择指南
TypeScript 的 Interface 与 Type 类型定义详解:语法、实战与选择指南 本文以《The Concise TypeScript Book》
文档教程The Concise TypeScript Book:interface 与 type 类型定义完全指南——语法、差异与工程选型
The Concise TypeScript Book:interface 与 type 类型定义完全指南——语法、差异与工程选型 本文基于 The Conci
文档教程The Concise TypeScript Book 指南:type 与 interface 的六大差异与选型实战
The Concise TypeScript Book 指南:type 与 interface 的六大差异与选型实战 type (类型别名)与 interfac
文档教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考