TypeScript核心语法入门 —— 类型注解与类型组合

50 阅读6分钟

阅读本文你能学到什么?

  • 什么是类型注解,为什么要用它
  • 如何为变量、数组添加类型约束
  • 联合类型和类型别名的使用场景
  • 开发中的注意事项与常见错误

前言

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 已有类型简单类型: numberstringbooleannullundefined
复杂类型: 数组、函数、对象
TS 新增类型联合类型、类型别名、接口(interface)、字面量类型、泛型、枚举、voidany

本章先聚焦基础类型,后续篇章会逐步展开接口、泛型等高级内容。

三、简单类型注解

简单类型的注解完全按照 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 简单类型一律使用小写numberstringboolean)。

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 = 10let a: number = 10使用小写 number 而非大写 Number
let b: object = {}let b: { name: string } = { name: 'Jack' }避免使用 object,应明确指定属性结构
let c: string[] | numberlet 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 = truetruefalse
数组(推荐)let d: number[] = [1, 2]数字组成的数组
数组(泛型)let e: Array<string> = ['a']字符串组成的数组
联合类型let f: string | number = 'hi'可以是字符串或数字
类型别名type MyList = number[]为类型起别名,便于复用

核心记忆口诀

类型注解小写写,数组用中括号,联合用竖线,别名用 type

下篇预告

📖 [第一篇:为什么学 TypeScript?—— 优势、场景与环境搭建]

掌握类型注解之后,下一章我们将学习如何为函数对象添加类型,这是 TypeScript 在实际项目中最高频的使用场景。

欢迎持续关注 🚀

参考资料

————

晓说前端 · 正在从“会写”到“搞懂”的路上

如果这篇文章帮到了你,点个关注,一起进阶。