文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载本文基于开源项目The Concise TypeScript Book法文原版章节与英文原版章节编写。TypeScript 中interface接口与type类型别名是描述数据形状的两大核心手段。本文将从二者最常用的声明语法讲起系统梳理基础类型、对象类型、Union联合与 Intersection交叉类型并对照仓库中《Differences between Type and Interface》等章节深入解析二者的声明合并、扩展方式与适用场景。读完本文你将能根据实际需求准确选择interface或type写出类型安全、可维护的 TypeScript 代码。一、Interface 与 Type 的通用声明语法在 TypeScript 中interface接口用于定义对象的形状它精确声明一个对象必须拥有的属性名、属性类型以及方法签名。定义一个接口的通用语法如下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; };说明原文档如 interface-and-type.md中的示例带有!-- skip --注释标记表示该代码片段是语法示意如Type1、ArgType1为占位符并不能直接编译通过实际项目中请使用真实类型名替换。在 TypeScript 中类型types用来定义数据的形状并强制类型检查。根据具体使用场景的不同TypeScript 有多种常用的类型定义语法下面逐一展开。二、基础类型Basic Types对变量声明进行类型标注是最基础的类型定义方式。仓库中《Type Annotations》章节明确指出对于使用var、let和const声明的变量可以可选地添加类型标注。以下是最常见的基础类型写法let myNumber: number 123; // number 类型 let myBoolean: boolean true; // boolean 类型 let myArray: string[] [a, b]; // 字符串数组 let myTuple: [string, number] [a, 123]; // 元组tuple要点说明number、boolean、string属于 TypeScript 的基础类型Primitive Types此外还有bigint、symbol、null、undefined、any等string[]表示元素类型为string的数组也可写作Arraystring元组[string, number]是固定长度、按顺序规定各位置元素类型的数组形态仓库另有《Tuple Type (Anonymous)》与《Fixed Length Tuple》专门讲解需要留意的是TypeScript 对简单类型的推断能力很强const x: number 1这类显式标注在多数场景下并非必需。仓库建议的一般原则是给函数签名参数与返回类型做标注但通常不必为函数体内部的局部变量做标注对象字面量则始终显式标注类型。三、对象与接口Objects and Interfaces对象类型描述一个对象的形状指明对象属性的名称、类型以及这些属性是必需还是可选详见仓库《Object Types》章节。对象的类型既可以用interface声明也可以用type别名声明还可以匿名内联地直接写在变量或函数参数上const x: { name: string; age: number } { name: Simon, age: 7 };上述代码直接在变量声明处内联了一个匿名对象类型要求x必须同时具备name: string与age: number两个属性。对象类型的两种正式定义方式// 方式一interface interface User { name: string; age: number; email?: string; // 问号表示可选属性 } // 方式二type 别名 type Point { x: number; y: number; };关于可选属性在属性名末尾追加问号?即可声明该属性可选。仓库《Optional Properties》章节进一步给出了可选属性配合默认值的典型用法type X { a: number; b?: number; // 可选 }; const x ({ a, b 100 }: X) a b;这里b未传入时使用默认值100实现可选但有兜底值的效果。匿名对象类型同样可以出现在函数参数中仓库《Object Types》章节的示例const sum (x: { a: number; b: number }) x.a x.b; console.log(sum({ a: 5, b: 1 })); // 6四、Union 与 Intersection 类型4.1 Union 联合类型|Union 类型表示一个值可以是若干种类型之一使用|符号连接每种可能的类型详见仓库《Union Type》章节type MyType string | number; // Union 类型 let myUnion: MyType hello; // 可以是 string myUnion 123; // 也可以是 number基本示例let x: string | number; x hello; // 合法 x 123; // 合法4.2 Intersection 交叉类型Intersection 类型表示一个值同时拥有两个或多个类型的全部属性使用符号连接详见仓库《Intersection Types》章节type TypeA { name: string }; type TypeB { age: number }; type CombinedType TypeA TypeB; // Intersection 类型 let myCombined: CombinedType { name: John, age: 25 }; // 同时具备 name 与 age 的对象仓库中的另一组示例更加直观type X { a: string; }; type Y { b: string; }; type J X Y; // Intersection const j: J { a: a, b: b, };需要强调Union 类型在运行时由你赋值给变量的值决定而 Intersection 类型在结构上要求对象必须同时满足所有组成类型的约束。五、Type 与 Interface 的关键差异这是本主题最容易被混淆的部分。仓库专门设有《Differences between Type and Interface》章节以下差异在该章节均有明确示例与论述。5.1 声明合并Declaration MergingInterface 独有Interface 支持声明合并declaration merging你可以多次声明同名 interfaceTypeScript 会将它们自动合并为一个包含全部属性与方法的单一接口。Type 不支持声明合并。这一特性在你想在不修改原始定义的前提下为已有类型补充功能、修补缺失或错误类型时非常有用。interface A { x: string; } interface A { y: string; } const j: A { x: xx, y: yy, };如果对A使用两次type声明同名别名TypeScript 会直接报重复标识符错误。5.2 扩展其他类型/接口语法不同Interface 和 Type都可以扩展其他类型/接口但语法不同Interface 使用extends关键字继承其他接口的属性和方法且可以同时继承多个接口。但 interface不能扩展复杂类型例如 union 类型。interface A { x: string; y: number; } interface B extends A { z: string; } const car: B { x: x, y: 123, z: z, };Type 使用运算符交叉类型把多个类型组合成一个类型interface A { x: string; y: number; } type B A { j: string; }; const c: B { x: x, y: 123, j: j, };仓库《Extending Types》章节对扩展能力做了更完整的总结interface 可以扩展 interface支持多继承interface A { a: string; } interface B { b: string; } interface Y extends A, B { y: string; }type 之间用交叉类型扩展type A { a: number; }; type B { b: number; }; type C A B;可以用 interface 扩展 type但反过来不行type A { a: string; }; interface B extends A { b: string; } // 合法interface extends type // 反例type 无法 extends interface // type C B extends ... // 语法不允许只能改用 5.3 Union/Intersection 的表达能力Type 更灵活在定义 Union 与 Intersection 类型时Type 更加灵活借助|与运算符可以轻松创建联合与交叉类型。而 interface 虽然可以间接地表示 union例如type C A | B这种两个 interface 的联合但没有内建对 intersection 的支持。用 type 定义业务模型中常见的组合形态type Department dep-x | dep-y; // Union type Person { name: string; age: number; }; type Employee { id: number; department: Department; }; type EmployeeInfo Person Employee; // IntersectionInterface 与 union 结合使用的示例interface A { x: x; } interface B { y: y; } type C A | B; // 两个 interface 的联合5.4 小结何时用 Interface何时用 Type综合原文档与仓库相关章节可以提炼出如下选用参考场景推荐原因需要声明合并同名多次声明、类型增强interface只有 interface 支持 declaration merging需要表达 unionA \| Btypeinterface 无内建 union 语法需要表达 intersectionA Btypeinterface 无内建交叉能力扩展对象形状、面向对象继承interface extends语义清晰支持多继承基于已有类型组合出新类型、映射类型、条件类型等复杂形态type表达式能力强可复用 union/交叉/泛型工具类型六、进阶延伸结合泛型与索引签名虽然本主题聚焦interface与type的声明与差异但二者都能与 TypeScript 的其他类型能力组合使用这里补充两点与类型定义紧密相关的实战延伸。6.1 泛型让类型定义可复用泛型允许把类型参数化从而让接口与类型别名在不同类型上复用详见仓库《Generics》章节。例如泛型函数与泛型类function identityT(arg: T): T { return arg; } const a identity(x); const b identity(123); class ContainerT { private item: T; constructor(item: T) { this.item item; } getItem(): T { return this.item; } } const numberContainer new Containernumber(123); console.log(numberContainer.getItem()); // 123泛型参数还可以用extends约束要求传入类型必须满足某个形状const printLen T extends { length: number }(value: T): void { console.log(value.length); }; printLen(Hello); // 5 printLen([1, 2, 3]); // 3 printLen(123); // 编译错误number 没有 length 属性6.2 索引签名定义键未知的对象当对象的键在编写代码时未知时可以用索引签名声明类型详见仓库《Index Signatures》与《Type Indexing》type DictionaryT { [key: string]: T; }; const myDict: Dictionarystring { a: a, b: b }; console.log(myDict[a]); // a索引键支持string、number与symbol。需要特别注意的是JavaScript 会自动把number索引转换为string索引因此k[1]与k[1]取到的是同一个值type K { [name: string | number]: string; }; const k: K { x: x, 1: b }; console.log(k[x]); console.log(k[1]); // b console.log(k[1]); // 与 k[1] 结果相同七、结语与实战建议综合原文档与仓库中《Type Annotations》、《Differences between Type and Interface》、《Extending Types》、《Object Types》等章节可以把本文的核心结论浓缩为四条实战建议描述对象形状interface与type均可胜任二者在普通对象上能力几乎等价按团队约定选用其一保持一致即可需要合并、增强、补丁优先用interface因为它支持声明合并需要 union / intersection / 映射等复杂类型运算优先用type表达能力更强写清楚签名、让编译器做推断函数参数与返回值建议显式标注类型const sum (a: number, b: number): number a b函数体内的局部变量交给 TypeScript 推断对象字面量则始终标注类型。关于更多类型定义细节可选属性、只读属性、索引签名、字面量类型、映射类型、条件类型等可继续阅读仓库中的《Object Types》、《Optional Properties》、《Readonly Properties》、《Type Manipulation》等章节其他语言版本的对应章节位于 fr-fr 等翻译目录下内容一致可作为多语言参考。赞分享文档教程【免费下载链接】typescript-bookThe Concise TypeScript Book: A Concise Guide to Effective Development in TypeScript. Free and Open Source.项目地址https://gitcode.com/gh_mirrors/typ/typescript-book点击查看免费下载相关推荐The Concise TypeScript Book 精讲Interface 与 Type 的语法、差异与实战取舍The Concise TypeScript Book 精讲Interface 与 Type 的语法、差异与实战取舍 本文以开源项目 The Concise文档教程The Concise TypeScript Book 精读Type 与 Interface 的差异全解析The Concise TypeScript Book 精读Type 与 Interface 的差异全解析 本篇技术指南围绕开源书籍 The Concise文档教程The Concise TypeScript Book 精读type 与 interface 的核心差异与实战选型The Concise TypeScript Book 精读type 与 interface 的核心差异与实战选型 导读 type 类型别名与 inter文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
