TypeScript
安装并使用 TypeScript
环境配置
安装 TypeScript
1 npm install typescript --save-dev
1 npm install -g typescript
编译 TS 文件
lite-server
用于轻量级开发的节点服务器,为 web 应用程序提供服务,在浏览器中打开它,在 html 或 javascript 更改时刷新,使用套接字注入 CSS 更改,并在找不到路由时具有回退页面。
https://www.npmjs.com/package/lite-server
1 npm install lite-server --save-dev
TypeScript 数据类型
PS:TypeScript 的类型系统只能在开发(编码)阶段辅助进行类型检查,TypeScript 最终会被编译成 JavaScript,而 JavaScript 本身不具备类型检查功能。
类型推断
联合数据类型
类型别名
unknown 类型
never 类型
TypeScript 编译
监视 TS 脚本的更新,然后实时编译为 JS 文件(监听单个文件)
多模块编译
在工程目录中执行这个命令后会自动生成一个tsconfig.json文件
此时执行 tsc --watch 就可以监视整个工程目录下的 TS 更新变化从而进行自动编译。
tsconfig.json 配置项:
exclude:在tsconfig.json配置文件中,可以针对需要编译排除的文件进行配置:
1 2 3 "exclude" : [ "node_modules" ]
include:在tsconfig.json配置文件中,可以指定需要编译的 TS 文件:
1 2 3 "include" : [ "index.ts" ]
TypeScript Class Interface
Class
声明一个 Class 类,并事例化这个 Class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Person { name : string ; constructor (name : string ) { this .name = name; } showInfo (): void { console .log (this .name ); } } const person = new Person ("Krian" );person.showInfo ();
可以直接在 constructor 构造器 入参中声明属性,并在对象初始化时,给这些属性进行赋值。
1 2 3 4 constructor (public name : string , private balance : number ) { }
只读属性:使用 readonly 关键字修饰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Person { name : string ; constructor (readonly name : string ) { this .name = name; } showInfo (): void { console .log (this .name ); } }
使用 private 关键字,声明一个属性为私有属性,提供 getter 和 setter 方法进行数据操作:
静态属性和方法:使用 static 关键字进行修饰
抽象类:使用 abstract 关键字声明一个抽象类 和 抽象方法
单例对象 私有化构造器:
继承
使用 extends 关键字实现 Class 类之间的继承关系
使用 protected 关键字声明一个属性为受保护的,无法通过外部直接访问,但是能实现子父类之间继承和重写。
Interface
interface 允许我们去定义一个对象的结构。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 interface Person { name : string ; age : number ; showInfo (): void ; } let person : Person ;person = { name : "krian" , age : 24 , showInfo ( ) { console .log (this .name , this .age ); }, }; person.showInfo ();
class 通过 implements 实现接口(多实现)。
在 interface 内部声明属性时,可以使用 readonly 直接声明为只读属性。
在属性名后面加 ? 声明这个属性是可选的。
第六章 TypeScript 高级类型概念笔记
6.1 - Module Introduction(模块介绍)
本章聚焦 TypeScript 高级类型概念,这些概念能解决实际项目中复杂的类型处理问题,核心内容包括交叉类型(Intersection Types)、类型守卫(Type Guards)、歧视联合(Discriminated Unions)、类型转换(Type Casting)、索引属性(Index Properties)、函数重载(Function Overloads)、可选链(Optional Chaining)、空值合并(Nullish Coalescing),旨在帮助开发者编写更灵活、类型更安全的代码。
6.2 - Intersection Types(交叉类型)
6.2.1 概念定义
交叉类型通过 & 符号将多个类型“合并”为一个新类型,新类型包含所有源类型的属性和方法,适用于需要“同时具备多个类型特征”的场景(例如一个对象既需要用户信息,又需要权限信息)。
语法格式 :
1 2 3 type TypeA = { propA : Type };type TypeB = { propB : Type };type IntersectionType = TypeA & TypeB ;
6.2.2 核心特性
属性合并 :若多个源类型有同名属性,且属性类型兼容(如 string 和 string),则合并后属性类型不变;若类型不兼容(如 string 和 number),则合并后属性类型为 never(表示该属性无合法值)。
方法合并 :若多个源类型有同名方法,合并后方法需兼容所有源方法的参数和返回值(即参数列表是所有源方法的“超集”,返回值是所有源方法的“子集”)。
6.2.3 实例演示
示例1:基础对象交叉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 type UserBase = { id : number ; name : string ; }; type UserPermission = { role : "admin" | "user" | "guest" ; hasEdit : boolean ; }; type User = UserBase & UserPermission ;const admin : User = { id : 1 , name : "Zhang San" , role : "admin" , hasEdit : true , }; const invalidUser : User = { id : 2 , name : "Li Si" , hasEdit : false , };
示例2:类型不兼容处理
1 2 3 4 5 6 7 8 type TypeX = { age : number };type TypeY = { age : string };type TypeXY = TypeX & TypeY ;const obj : TypeXY = { age : 20 , };
6.3 - More on Type Guards(深入理解类型守卫)
6.3.1 概念定义
类型守卫是一组“运行时检查逻辑”,用于判断一个值的具体类型,从而在条件分支中缩小类型范围(Type Narrowing),避免类型错误。TypeScript 会识别常见的类型守卫逻辑,并自动更新变量的类型推断。
6.3.2 常见类型守卫实现方式
1. typeof 类型守卫(适用于基本类型)
用于判断 string、number、boolean、symbol 等基本类型,不能用于对象类型 (typeof {} 会返回 object,无法区分 Array、Date 等)。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function formatValue (value : string | number | boolean ) { if (typeof value === "string" ) { return `String: ${value.toUpperCase()} ` ; } else if (typeof value === "number" ) { return `Number: ${value.toFixed(2 )} ` ; } else { return `Boolean: ${value ? "Yes" : "No" } ` ; } } console .log (formatValue ("hello" )); console .log (formatValue (123.456 )); console .log (formatValue (false ));
2. instanceof 类型守卫(适用于引用类型)
用于判断一个对象是否是某个类的实例(基于原型链),适用于 Array、Date、自定义类等引用类型。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function handleValue (value : Date | Array <string > | string ) { if (value instanceof Date ) { return `Date: ${value.toLocaleDateString()} ` ; } else if (value instanceof Array ) { return `Array: [${value.join(", " )} ]` ; } else { return `String: ${value} ` ; } } console .log (handleValue (new Date (2024 , 5 , 1 ))); console .log (handleValue (["a" , "b" , "c" ])); console .log (handleValue ("test" ));
3. 自定义类型守卫(适用于复杂对象)
通过“返回值为 parameter is Type”的函数,自定义类型判断逻辑,适用于区分结构相似的对象类型。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 type Circle = { type : "circle" ; radius : number ; }; type Rectangle = { type : "rectangle" ; width : number ; height : number ; }; type Shape = Circle | Rectangle ;function isCircle (shape : Shape ): shape is Circle { return shape.type === "circle" ; } function isRectangle (shape : Shape ): shape is Rectangle { return shape.type === "rectangle" ; } function calculateArea (shape : Shape ): number { if (isCircle (shape)) { return Math .PI * shape.radius ** 2 ; } else if (isRectangle (shape)) { return shape.width * shape.height ; } return 0 ; } const circle : Circle = { type : "circle" , radius : 5 };const rectangle : Rectangle = { type : "rectangle" , width : 4 , height : 6 };console .log (calculateArea (circle)); console .log (calculateArea (rectangle));
6.4 - Discriminated Unions(歧视联合)
6.4.1 概念定义
歧视联合(又称“可区分联合”)是一种特殊的联合类型,满足两个条件:
所有成员类型都包含一个同名且类型不同的“歧视属性” (如 type: "circle" 或 type: "rectangle");
通过该歧视属性的取值,可以唯一确定当前值属于哪个成员类型。
歧视联合的核心优势是:无需复杂的类型守卫,仅通过歧视属性即可缩小类型范围 ,代码更简洁、可读性更高。
6.4.2 实例演示
示例1:基础歧视联合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 type PaymentMethod = | { type : "cash" ; amount : number } | { type : "card" ; cardNumber : string ; expiryDate : string } | { type : "wechat" ; openId : string ; amount : number }; function processPayment (method : PaymentMethod ): string { switch (method.type ) { case "cash" : return `Cash payment: $${method.amount.toFixed(2 )} ` ; case "card" : return `Card payment: ****${method.cardNumber.slice(-4 )} , Expiry: ${method.expiryDate} ` ; case "wechat" : return `WeChat payment: OpenId ${method.openId.slice(0 , 8 )} ..., Amount: $${method.amount.toFixed(2 )} ` ; } } console .log (processPayment ({ type : "cash" , amount : 50.5 }));console .log ( processPayment ({ type : "card" , cardNumber : "1234567890123456" , expiryDate : "12/26" , }), ); console .log ( processPayment ({ type : "wechat" , openId : "o6_bmjrPTlm6_2sgVt7hMZOPfL2M" , amount : 100 , }), );
示例2:结合类型守卫使用
当歧视属性的判断逻辑较复杂时,可结合自定义类型守卫进一步简化代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 type Book = { category : "book" ; isbn : string };type Movie = { category : "movie" ; duration : number };type Media = Book | Movie ;function isBook (media : Media ): media is Book { return media.category === "book" ; } function getMediaInfo (media : Media ): string { if (isBook (media)) { return `Book: ISBN ${media.isbn} ` ; } else { return `Movie: ${media.duration} minutes` ; } } console .log (getMediaInfo ({ category : "book" , isbn : "9787115546026" }));console .log (getMediaInfo ({ category : "movie" , duration : 120 }));
6.5 - Type Casting(类型转换)
6.5.1 概念定义
类型转换(又称“类型断言”)用于告诉 TypeScript 编译器“我比你更清楚这个值的类型” ,强制将一个类型转换为另一个类型。它仅在编译阶段生效,不会影响运行时的类型(即不会改变值本身),适用于编译器无法正确推断类型的场景(如 DOM 元素获取、第三方库返回值处理)。
6.5.2 两种语法格式
1. “尖括号”语法(不支持 JSX 环境)
1 2 const value : unknown = "hello world" ;const length = (<string >value).length ;
2. as 语法(推荐,支持所有环境,包括 JSX)
1 2 const value : unknown = "hello world" ;const length = (value as string ).length ;
6.5.3 适用场景与注意事项
场景1:DOM 元素获取
TypeScript 无法自动推断 document.getElementById 等方法返回的 DOM 元素具体类型(默认返回 HTMLElement | null),需通过类型转换指定具体元素类型(如 HTMLInputElement、HTMLButtonElement)。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const input = document .getElementById ("username-input" );console .log (input.value ); const usernameInput = document .getElementById ( "username-input" , ) as HTMLInputElement | null ; if (usernameInput) { console .log (usernameInput.value ); }
场景2:未知类型(unknown)处理
当变量类型为 unknown 时,TypeScript 禁止直接访问其属性或方法,需通过类型转换明确类型。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function getThirdPartyData ( ): unknown { return { name : "Wang Wu" , age : 30 }; } const data = getThirdPartyData ();console .log (data.name ); type UserData = { name : string ; age : number };const userData = data as UserData ;console .log (userData.name ); console .log (userData.age );
注意事项
避免“过度转换” :若转换后的类型与运行时实际类型不匹配,会导致运行时错误(如将 number 转换为 string 后访问 length 属性)。
优先使用类型守卫 :类型转换是“强制断言”,而类型守卫是“运行时检查”,若能通过类型守卫确定类型,优先使用类型守卫(更安全)。
null/undefined 处理 :TypeScript 严格模式下,需先判断变量非 null/undefined,再进行类型转换(避免 null as Type 导致的运行时错误)。
6.6 - Index Properties(索引属性)
6.6.1 概念定义
索引属性(又称“索引签名”)用于定义属性名不确定,但属性类型有规律 的对象类型。它允许通过“字符串索引”或“数字索引”访问对象属性,适用于动态生成属性名的场景(如配置对象、字典映射)。
6.6.2 两种索引类型
1. 字符串索引(最常用)
语法:{ [key: string]: ValueType },表示“所有属性名是字符串的属性,其类型均为 ValueType”。
示例1:基础字典类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 type NumberDictionary = { [key : string ]: number ; length : number ; }; const scores : NumberDictionary = { math : 90 , english : 85 , length : 2 , }; console .log (scores.math ); console .log (scores["english" ]); console .log (scores.length ); const invalidScores : NumberDictionary = { math : "90" , };
示例2:结合可选属性与只读属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 type UserConfig = { readonly [key : string ]: string | number | boolean ; theme ?: string ; }; const config : UserConfig = { theme : "dark" , fontSize : 16 , autoSave : true , }; config.fontSize = 14 ;
2. 数字索引(适用于类数组对象)
语法:{ [index: number]: ValueType },表示“所有属性名是数字的属性,其类型均为 ValueType”,常用于类数组对象(如 NodeList、自定义数组结构)。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 type StringArray = { [index : number ]: string ; length : number ; push : (item : string ) => void ; }; const fruits : StringArray = { 0 : "apple" , 1 : "banana" , 2 : "orange" , length : 3 , push : function (item ) { this [this .length ] = item; this .length ++; }, }; console .log (fruits[0 ]); fruits.push ("grape" ); console .log (fruits.length ); console .log (fruits[3 ]);
6.6.3 注意事项
索引类型与显式属性的兼容性 :显式定义的属性名若符合索引类型(如字符串索引中显式定义 length: number),其类型必须与索引值类型一致,否则会报错。
字符串索引与数字索引的关系 :若同时定义字符串索引和数字索引,数字索引的值类型必须是字符串索引值类型的“子集”(因为 JavaScript 中数字键会自动转换为字符串键,如 obj[1] 等价于 obj["1"])。
错误示例 :
1 2 3 4 5 type InvalidIndexType = { [key : string ]: number ; [index : number ]: string ; };
6.7 - Function Overloads(函数重载)
6.7.1 概念定义
函数重载允许为同一个函数定义多个“参数类型+返回值类型”的组合 ,使函数能处理不同类型的输入,并返回对应的输出类型,解决了“单一函数类型无法覆盖多种调用场景”的问题(如 add 函数既可以加数字,也可以拼接字符串)。
TypeScript 的函数重载本质是“类型层面的多态”,编译后会合并为一个函数(运行时仍为一个函数),仅在编译阶段进行类型检查。
6.7.2 语法格式
重载签名(Overload Signatures) :定义多个函数的“参数类型+返回值类型”组合,仅声明类型,不包含实现。
实现签名(Implementation Signature) :定义函数的实际实现逻辑,其参数类型和返回值类型必须“覆盖所有重载签名”(即能兼容所有重载场景)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function func (param1 : number , param2 : number ): number ;function func (param1 : string , param2 : string ): string ;function func ( param1 : number | string , param2 : number | string , ): number | string { if (typeof param1 === "number" && typeof param2 === "number" ) { return param1 + param2; } else if (typeof param1 === "string" && typeof param2 === "string" ) { return param1 + param2; } throw new Error ("Invalid parameter types" ); }
6.7.3 实例演示
示例1:基础函数重载(加法与字符串拼接)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 function add (a : number , b : number ): number ;function add (a : string , b : string ): string ;function add (a : number | string , b : number | string ): number | string { if (typeof a === "number" && typeof b === "number" ) { return a + b; } else if (typeof a === "string" && typeof b === "string" ) { return a + b; } throw new Error ("Both parameters must be the same type (number or string)" ); } console .log (add (10 , 20 )); console .log (add ("Hello, " , "TypeScript" )); console .log (add (10 , "20" ));
示例2:可选参数与重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function calculate (x : number ): number ;function calculate (x : number , y : number ): number ;function calculate (x : number , y ?: number ): number { if (y === undefined ) { return x ** 2 ; } else { return x + y; } } console .log (calculate (5 )); console .log (calculate (5 , 3 )); console .log (calculate (5 , 3 , 2 ));
6.7.4 注意事项
重载签名顺序 :重载签名应从“具体”到“宽泛”排序,因为 TypeScript 会按顺序匹配重载签名,若宽泛的签名在前,会优先匹配,导致具体签名无法生效。
错误示例(顺序不当) :
1 2 3 4 5 6 7 8 9 function func (a : number | string ): void ;function func (a : number ): void ; function func (a : number | string ): void { console .log (a); } func (10 );
实现签名必须兼容所有重载签名 :实现签名的参数类型必须是所有重载签名参数类型的“联合类型”,返回值类型必须是所有重载签名返回值类型的“联合类型”,否则会报错。
6.8 - Optional Chaining(可选链)
6.8.1 概念定义
可选链通过 ?. 运算符简化“嵌套对象属性访问”的逻辑,当访问的属性或方法不存在(即值为 null 或 undefined)时,不会抛出 Cannot read property 'x' of undefined 错误,而是直接返回 undefined,适用于处理“可能存在缺失的嵌套结构”(如 API 返回的复杂数据)。
6.8.2 语法与适用场景
1. 访问嵌套对象属性(obj?.prop?.nestedProp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 type User = { name : string ; address ?: { city : string ; street ?: string ; }; }; const user1 : User = { name : "Zhang San" , address : { city : "Beijing" , }, }; const user2 : User = { name : "Li Si" , }; console .log (user1.address ?.city ); console .log (user1.address ?.street ); console .log (user2.address ?.city ); console .log (user2.address && user2.address .city );
2. 访问数组元素(arr?.[index])
当数组可能为 null 或 undefined 时,使用 arr?.[index] 避免访问不存在的数组元素。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 const fruits : string [] | null = Math .random () > 0.5 ? ["apple" , "banana" ] : null ; console .log (fruits?.[0 ]); console .log (fruits?.length ); if (fruits) { console .log (fruits[0 ]); }
3. 调用可能不存在的方法(func?.())
当函数可能为 null 或 undefined 时,使用 func?.() 避免调用不存在的方法。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type Logger = { log ?: (message : string ) => void ; }; const validLogger : Logger = { log : (message ) => console .log (`Log: ${message} ` ), }; const invalidLogger : Logger = {}; validLogger.log ?.("Hello" ); invalidLogger.log ?.("Test" ); if (invalidLogger.log ) { invalidLogger.log ("Test" ); }
6.8.3 注意事项
可选链不替代空值处理 :可选链仅返回 undefined,若需要默认值,需结合“空值合并运算符(??)”使用(见 6.9 节)。
避免过度使用 :仅在属性/方法“确实可能缺失”时使用可选链,若属性是“必须存在”的,应通过类型定义强制要求,而非依赖可选链(避免隐藏逻辑错误)。
6.9 - Nullish Coalescing(空值合并)
6.9.1 概念定义
空值合并通过 ?? 运算符为“可能为 null 或 undefined 的值”设置默认值,仅当左侧值为 null 或 undefined 时,才返回右侧的默认值;若左侧值为 0、""、false 等“假值”,仍返回左侧值,解决了“逻辑或(||)运算符误判假值”的问题。
6.9.2 与逻辑或(||)的区别
| 运算符 | 触发默认值的条件 | 适用场景 |
| ------ | ------------------------------ | ------------------------------------ | ------------------------------------------------------- | ------------------------ |
| | | | 左侧为“假值”(0、""、false、null、undefined) | 希望所有假值都使用默认值 |
| ?? | 左侧仅为 null 或 undefined | 仅希望 null/undefined 使用默认值 |
示例:对比两者差异
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const count1 = 0 ;console .log (count1 || 10 ); console .log (count1 ?? 10 ); const username1 = "" ;console .log (username1 || "Guest" ); console .log (username1 ?? "Guest" ); const age1 = null ;console .log (age1 || 18 ); console .log (age1 ?? 18 ); const age2 = undefined ;console .log (age2 || 18 ); console .log (age2 ?? 18 );
6.9.3 结合可选链使用(常见场景)
在处理嵌套对象或 API 数据时,常将“可选链(?.)”与“空值合并(??)”结合,既避免访问不存在的属性报错,又能为缺失的值设置默认值。
示例 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type User = { name : string ; age ?: number ; address ?: { city ?: string ; }; }; const user : User = { name : "Wang Wu" , }; const userAge = user.age ?? 18 ; const userCity = user.address ?.city ?? "Unknown City" ; console .log (userAge); console .log (userCity);
6.9.4 注意事项
优先级 :?? 运算符的优先级低于算术运算符、比较运算符和逻辑与(&&),但高于赋值运算符,若表达式中包含其他运算符,建议使用括号明确优先级。
示例 :
1 2 3 4 5 6 7 8 const a = 10 ;const b = null ;console .log (a + b ?? 5 );console .log (a + (b ?? 5 ));
不能与 &&/|| 混用(无括号时) :TypeScript 禁止在无括号的情况下将 ?? 与 && 或 || 混用,避免歧义,需使用括号明确逻辑。
错误示例 :
1 2 3 4 5 6 const result = (a || b) ?? c; const result1 = (a || b) ?? c; const result2 = a || (b ?? c);
6.10 - Wrap Up(本章总结)
本章围绕 TypeScript 高级类型概念展开,核心目标是解决“复杂场景下的类型安全”问题,各知识点的核心价值与适用场景如下:
知识点
核心价值
适用场景
交叉类型(&)
合并多个类型的属性/方法
需要对象同时具备多个类型特征(如用户+权限)
类型守卫
运行时缩小类型范围,避免类型错误
区分联合类型中的具体类型(如 Date vs Array)
歧视联合
通过歧视属性简化联合类型判断
处理结构相似但类型不同的对象(如不同支付方式)
类型转换(as)
告诉编译器值的实际类型,解决推断失效问题
DOM 元素获取、第三方库类型适配
索引属性
定义属性名不确定但类型有规律的对象
字典映射、动态配置对象
函数重载
为同一函数定义多种参数/返回值类型组合
处理多种输入类型(如数字加法 vs 字符串拼接)
可选链(?.)
简化嵌套属性访问,避免 null/undefined 报错
处理 API 复杂数据、可能缺失的嵌套结构
空值合并(??)
为 null/undefined 设置默认值,不误判假值
为缺失属性设置默认值(如 0、"" 需保留)
TypeScript Decorator 装饰器
使用 Decorator 需要在 tsconfig.json 中进行配置:
1 "experimentalDecorators" : true
TypeScript 结合 DOM
DOM 元素对应的 TS 的类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 interface HTMLElementTagNameMap { a : HTMLAnchorElement ; abbr : HTMLElement ; address : HTMLElement ; applet : HTMLAppletElement ; area : HTMLAreaElement ; article : HTMLElement ; aside : HTMLElement ; audio : HTMLAudioElement ; b : HTMLElement ; base : HTMLBaseElement ; bdi : HTMLElement ; bdo : HTMLElement ; blockquote : HTMLQuoteElement ; body : HTMLBodyElement ; br : HTMLBRElement ; button : HTMLButtonElement ; canvas : HTMLCanvasElement ; caption : HTMLTableCaptionElement ; cite : HTMLElement ; code : HTMLElement ; col : HTMLTableColElement ; colgroup : HTMLTableColElement ; data : HTMLDataElement ; datalist : HTMLDataListElement ; dd : HTMLElement ; del : HTMLModElement ; details : HTMLDetailsElement ; dfn : HTMLElement ; dialog : HTMLDialogElement ; dir : HTMLDirectoryElement ; div : HTMLDivElement ; dl : HTMLDListElement ; dt : HTMLElement ; em : HTMLElement ; embed : HTMLEmbedElement ; fieldset : HTMLFieldSetElement ; figcaption : HTMLElement ; figure : HTMLElement ; font : HTMLFontElement ; footer : HTMLElement ; form : HTMLFormElement ; frame : HTMLFrameElement ; frameset : HTMLFrameSetElement ; h1 : HTMLHeadingElement ; h2 : HTMLHeadingElement ; h3 : HTMLHeadingElement ; h4 : HTMLHeadingElement ; h5 : HTMLHeadingElement ; h6 : HTMLHeadingElement ; head : HTMLHeadElement ; header : HTMLElement ; hgroup : HTMLElement ; hr : HTMLHRElement ; html : HTMLHtmlElement ; i : HTMLElement ; iframe : HTMLIFrameElement ; img : HTMLImageElement ; input : HTMLInputElement ; ins : HTMLModElement ; kbd : HTMLElement ; label : HTMLLabelElement ; legend : HTMLLegendElement ; li : HTMLLIElement ; link : HTMLLinkElement ; main : HTMLElement ; map : HTMLMapElement ; mark : HTMLElement ; marquee : HTMLMarqueeElement ; menu : HTMLMenuElement ; meta : HTMLMetaElement ; meter : HTMLMeterElement ; nav : HTMLElement ; noscript : HTMLElement ; object : HTMLObjectElement ; ol : HTMLOListElement ; optgroup : HTMLOptGroupElement ; option : HTMLOptionElement ; output : HTMLOutputElement ; p : HTMLParagraphElement ; param : HTMLParamElement ; picture : HTMLPictureElement ; pre : HTMLPreElement ; progress : HTMLProgressElement ; q : HTMLQuoteElement ; rp : HTMLElement ; rt : HTMLElement ; ruby : HTMLElement ; s : HTMLElement ; samp : HTMLElement ; script : HTMLScriptElement ; section : HTMLElement ; select : HTMLSelectElement ; slot : HTMLSlotElement ; small : HTMLElement ; source : HTMLSourceElement ; span : HTMLSpanElement ; strong : HTMLElement ; style : HTMLStyleElement ; sub : HTMLElement ; summary : HTMLElement ; sup : HTMLElement ; table : HTMLTableElement ; tbody : HTMLTableSectionElement ; td : HTMLTableDataCellElement ; template : HTMLTemplateElement ; textarea : HTMLTextAreaElement ; tfoot : HTMLTableSectionElement ; th : HTMLTableHeaderCellElement ; thead : HTMLTableSectionElement ; time : HTMLTimeElement ; title : HTMLTitleElement ; tr : HTMLTableRowElement ; track : HTMLTrackElement ; u : HTMLElement ; ul : HTMLUListElement ; var : HTMLElement ; video : HTMLVideoElement ; wbr : HTMLElement ; }
当我们使用getElementById等等其他方法获取元素时,返回结果可能为null,但是我们能确保在 HTML 中我们一定能拿到这个元素,可以使用 ! 声明一定可以获取到对应元素。
1 const appDom = document .getElementById ("app" )! as HTMLDivElement ;
TypeScript 多文件 Multiple Files
namespace
ES module
TypeScript 结合 Webpack
https://webpack.js.org/
安装指令:
1 2 npm install --save-dev webpack webpack-cli webpack-dev-server npm install --save-dev typescript ts-loader
package.json
1 2 3 4 5 6 7 8 "devDependencies" : { "ts-loader" : "^9.5.2" , "typescript" : "^5.7.3" , "webpack" : "^5.98.0" , "webpack-cli" : "^6.0.1" , "webpack-dev-server" : "^5.2.0" } npm install --save-dev clean-webpack-plugin
TypeScript 结合 三方库
Lodash
解决 TS 不识别 JS 原生三方库抛出异常问题
1 npm install --save-dev @type/lodash
使用 declare 关键字声明变量存在
class-validator
TypeScript 结合 Axios
TypeScript 结合 Vue
TypeScript 结合 Node