阅读本文你能学到什么?
- 什么是类型注解,为什么要用它
- 如何为变量、数组添加类型约束
- 联合类型和类型别名的使用场景
- 开发中的注意事项与常见错误
前言
TypeScript 最核心的特性就是类型系统,而类型注解是进入类型世界的第一道门。
很多初学者会问:“不就是给变量加个类型吗?有什么好学的?”
可别小看这个类型注解,它可不只是"加个标签"那么简单,至少能帮你搞定三件大事:
-
🛡️ 更安全 —— 在编码阶段就发现类型错误
-
💡 更智能 —— 编辑器提供精准的代码提示
-
📖 更可读 —— 类型本身即是最好的文档
本文将从零开始,带你彻底掌握 TypeScript 的类型注解。
一、类型注解是什么
类型注解是指为变量添加类型约束,让变量只能被赋值为约定好的类型,同时还能获得对应的代码提示与智能补全。
let msg: string = 'Hello TypeScript'
// ↑
// 这就是类型注解,约束 msg 只能是字符串
说明:
:string就是类型注解,约束变量 msg 只能被赋值为 string 类型,同时可以有 string 类型的相关提示(如 .charAt()、.concat()、.substring() 等方法)。
为什么需要类型注解?
对比一下有无类型注解的区别:
// ❌ 没有类型注解(JavaScript 写法)
function add(a, b) {
return a + b
}
add(1, '2') // 结果是 '12',完全不符合预期,但不会报错!
// ✅ 有类型注解(TypeScript 写法)
function add(a: number, b: number): number {
return a + b
}
add(1, '2') // ❌ TypeScript 直接报错:类型“string”不能赋值给类型“number”
类型注解的价值:把运行时错误提前到编译时发现。
二、常用类型概览
TypeScript 中的类型主要分为两大类:
| 分类 | 包含类型 |
|---|---|
| JS 已有类型 | 简单类型: number、string、boolean、null、undefined复杂类型: 数组、函数、对象 |
| TS 新增类型 | 联合类型、类型别名、接口(interface)、字面量类型、泛型、枚举、void、any 等 |
本章先聚焦基础类型,后续篇章会逐步展开接口、泛型等高级内容。
三、简单类型注解
简单类型的注解完全按照 JavaScript 中的类型名称(全小写格式)来书写即可。
3.1 语法
变量:类型
3.2 示例
let age: number = 18 // ✅ 数字类型
let name: string = 'Jack' // ✅ 字符串类型
let isLoading: boolean = false // ✅ 布尔类型
let nullValue: null = null // ⚠️ 极少这样用
let undefinedValue: undefined = undefined // ⚠️ 极少这样用
⚠️ 常见错误:首字母大写
初学者容易写成 JavaScript 的包装类型(首字母大写):// ❌ 错误 let age: Number = 18 // ✅ 正确 let age: number = 18记住:TypeScript 简单类型一律使用小写(
number、string、boolean)。
3.3 关于 null 和 undefined
null 和 undefined 在实际开发中很少单独注解,更多用于联合类型:
// ❌ 极少这样用
let data: null = null
// ✅ 更常见的用法:联合类型
let data: string | null = 'hello'
data = null // 允许
这种“可能是字符串,也可能是空”的场景非常常见,比如后端接口返回的数据。
四、数组类型注解(重点)
给变量加上数组类型注解后,能带来两个很实用的好处:
4.1 数组注解的好处
① 既限制变量为数组,又限制数组成员的类型
let numbers: number[] = [1, 2, 3]
numbers.push('4') // ❌ 报错:类型“string”不能赋值给类型“number”
② 编码时既有数组方法提示,也有成员方法提示
当你操作数组时,编辑器会智能提示:
-
数组本身的方法:.push()、.pop()、.map()、.filter() 等
-
数组成员的属性和方法(如字符串的 .toUpperCase())
4.2 如何注解数组类型
TypeScript 提供了两种数组注解方式:
4.2.1 语法一:元素类型 + [](推荐 ✅)
在元素类型后面接上 [],表示由此类型元素组成的一个数组,例如:
let numbers: number[] = [1, 2, 3] // 数组成员只能是数字
let names: string[] = ['Alice', 'Bob'] // 数组成员只能是字符串
4.2.2 语法二:数组泛型 Array<元素类型>
使用数组泛型,Array<元素类型>,例如:
let numbers: Array<number> = [1, 2, 3]
let names: Array<string> = ['Alice', 'Bob']
推荐使用语法一(类型[]),写法更简洁,也是社区的主流风格。
五、联合类型和别名类型
5.1 联合类型(Union Types)
联合类型说白了就是"或"的关系 —— 通过竖线 | 连接多个类型,表示变量可以是其中任意一种类型。
// 变量可以是 string 或 number
let id: string | number
id = 'user-001' // ✅
id = 1001 // ✅
id = true // ❌ 报错:boolean 不在联合类型中
联合类型在数组中的应用:
// 数组中每个元素可以是 string 或 number
let arr: (string | number)[] = [1, 'name']
⚠️ 注意括号不能省略:(string | number)[] 表示"数组中的每个元素是 string 或 number";而 string | number[] 表示"要么是 string,要么是 number 数组",含义完全不同!
实际开发场景:
// 接口返回的数据可能是对象,也可能是 null(表示未找到)
function getUser(id: number): { name: string } | null {
const user = database.find(id)
return user || null
}
5.2 类型别名(Type Aliases)
通过 type 关键字为复杂类型起一个别名,方便你到处复用,不用反复写一堆。
// 定义类型别名
type ItemType= (string | number)[]
// 复用同一个类型
let studentList: ItemType = [1, '小明', 2, '小红']
let teacherList: ItemType = ['T001', '张老师', 'T002', '李老师']
let productIds: ItemType = [1001, 'P1002', 1003]
命名规范:类型别名推荐使用大驼峰命名法(PascalCase),如 ItemType、UserId、ApiResponse。
类型别名的更多用法:
// 为联合类型起别名
type ID = string | number
// 为对象类型起别名
type User = {
name: string
age: number
}
// 使用别名
let userId: ID = 'u001'
let user: User = { name: 'Jack', age: 18 }
六、开发中的常见错误与避坑指南
| 常见错误 | 正确写法 | 说明 |
|---|---|---|
let a: Number = 10 | let a: number = 10 | 使用小写 number 而非大写 Number |
let b: object = {} | let b: { name: string } = { name: 'Jack' } | 避免使用 object,应明确指定属性结构 |
let c: string[] | number | let c: (string | number)[] | 注意括号位置,含义完全不同 |
let d: [] = [] | let d: any[] = [] 或 let d: unknown[] = [] | 空数组类型应明确成员类型 |
🔥 高频错误详解
错误一:类型"string"不能赋值给类型"number"
let age: number = '18' // ❌ 报错
// 解决:age 要么改成 string 类型,要么赋值为数字
错误二:数组类型不匹配
let arr: number[] = [1, 2, '3'] // ❌ 报错
// 解决:如果确实需要混合类型,使用 (string | number)[]
let arr: (string | number)[] = [1, 2, '3'] // ✅
七、本篇小结
| 类型 | 注解示例 | 说明 |
|---|---|---|
| 数字 | let a: number = 10 | 整数或浮点数 |
| 字符串 | let b: string = 'hi' | 文本数据 |
| 布尔 | let c: boolean = true | true 或 false |
| 数组(推荐) | let d: number[] = [1, 2] | 数字组成的数组 |
| 数组(泛型) | let e: Array<string> = ['a'] | 字符串组成的数组 |
| 联合类型 | let f: string | number = 'hi' | 可以是字符串或数字 |
| 类型别名 | type MyList = number[] | 为类型起别名,便于复用 |
核心记忆口诀
类型注解小写写,数组用中括号,联合用竖线,别名用 type
下篇预告
📖 [第一篇:为什么学 TypeScript?—— 优势、场景与环境搭建]
掌握类型注解之后,下一章我们将学习如何为函数和对象添加类型,这是 TypeScript 在实际项目中最高频的使用场景。
欢迎持续关注 🚀
参考资料
————
晓说前端 · 正在从“会写”到“搞懂”的路上
如果这篇文章帮到了你,点个关注,一起进阶。