本文献给:
已掌握JavaScript基础,希望系统学习TypeScript类型系统的开发者。本文将深入讲解TypeScript中最基础的三种原始类型,以及如何通过类型注解和类型推断让代码更安全、更可读。
你将学到:
- 类型注解的基本语法与使用场景
- TypeScript的类型推断机制
- 为变量、常量、函数参数标注类型
- 常见错误
目录
- 一、为什么需要类型系统?
- [二、类型注解(Type Annotation)](#二、类型注解(Type Annotation))
-
- [2.1 什么是类型注解](#2.1 什么是类型注解)
- [2.2 为什么需要显式注解?](#2.2 为什么需要显式注解?)
- [三、三种基础类型:string / number / boolean](#三、三种基础类型:string / number / boolean)
-
- [3.1 string](#3.1 string)
- [3.2 number](#3.2 number)
- [3.3 boolean](#3.3 boolean)
- [3.4 类型注解的位置](#3.4 类型注解的位置)
- [四、类型推断(Type Inference)](#四、类型推断(Type Inference))
-
- [4.1 变量初始化推断](#4.1 变量初始化推断)
- [4.2 函数返回值推断](#4.2 函数返回值推断)
- [4.3 最佳通用类型推断](#4.3 最佳通用类型推断)
- [4.4 何时依赖推断,何时显式注解?](#4.4 何时依赖推断,何时显式注解?)
- 五、函数参数的类型注解
-
- [5.1 基本参数注解](#5.1 基本参数注解)
- [5.2 可选参数与默认参数](#5.2 可选参数与默认参数)
- [5.3 剩余参数](#5.3 剩余参数)
- 六、常见错误与注意事项
-
- [6.1 "变量隐式具有 any 类型"](#6.1 “变量隐式具有 any 类型”)
- [6.2 类型不匹配的赋值](#6.2 类型不匹配的赋值)
- [6.3 函数返回值类型不匹配](#6.3 函数返回值类型不匹配)
- [6.4 忽略函数返回值类型注解的后果](#6.4 忽略函数返回值类型注解的后果)
- 七、综合示例
- 八、小结
一、为什么需要类型系统?
JavaScript 是动态类型语言,变量可以随时改变类型,这带来了灵活性,但也埋下了隐患:
javascript
// JavaScript 中的问题
function greet(name) {
return "Hello, " + name;
}
let user = "Alice";
console.log(greet(user)); // "Hello, Alice"
user = 42;
console.log(greet(user)); // "Hello, 42" ------ 并没有报错,但语义错误!
TypeScript 通过静态类型检查,在编译阶段就能发现这类问题:
typescript
function greet(name: string) {
return "Hello, " + name;
}
let user = "Alice";
greet(user); // OK
user = 42;
greet(user); // ❌ 编译错误:类型"number"的参数不能赋给类型"string"的参数
二、类型注解(Type Annotation)
2.1 什么是类型注解
类型注解是为变量、函数参数、返回值等显式指定类型 的语法,形式为 : 类型。
typescript
// 变量类型注解
let name: string = "Alice";
let age: number = 25;
let isStudent: boolean = false;
// 函数参数与返回值注解
function add(x: number, y: number): number {
return x + y;
}
2.2 为什么需要显式注解?
虽然TypeScript能自动推断很多类型,但某些场景下显式注解必不可少:
- 函数参数:参数无法从调用处推断,必须注解
- 函数返回值:明确契约,防止意外返回错误类型
- 变量声明时未初始化 :此时无法推断,默认为
any - 希望强制类型:即使能推断,也显式写出以增强可读性
typescript
// 未初始化的变量
let data; // 类型被推断为 any(不推荐)
let data2: string; // 显式注解为 string,后续只能赋字符串
三、三种基础类型:string / number / boolean
3.1 string
表示文本字符串,可以使用单引号、双引号或模板字符串。
typescript
let greeting: string = "Hello";
let name: string = 'Alice';
let message: string = `Welcome, ${name}!`;
3.2 number
TypeScript中的所有数字(整数、浮点数、负数、NaN、Infinity)都使用 number 类型,不区分整型和浮点型。
typescript
let decimal: number = 42;
let hex: number = 0x2a; // 十六进制
let binary: number = 0b101010; // 二进制
let octal: number = 0o52; // 八进制
let float: number = 3.14;
let negative: number = -5;
let notANumber: number = NaN;
let infinity: number = Infinity;
3.3 boolean
只有两个值:true 和 false。
typescript
let isDone: boolean = false;
let isEnabled: boolean = true;
3.4 类型注解的位置
- 变量声明 :
let 变量名: 类型 = 值; - 常量声明 :
const 常量名: 类型 = 值;(通常可省略,因为常量值不变,推断足够准确) - 函数参数 :
function func(param: 类型) {} - 函数返回值 :
function func(): 类型 {}
typescript
// 常量注解通常冗余,但仍合法
const PI: number = 3.14159; // 可省略 :number
// 函数返回值注解
function getRandom(): number {
return Math.random();
}
四、类型推断(Type Inference)
TypeScript 能在很多情况下自动推断出变量的类型,无需显式注解。
4.1 变量初始化推断
typescript
let message = "Hello"; // 推断为 string
let count = 10; // 推断为 number
let isLoading = false; // 推断为 boolean
// 后续赋值必须匹配推断类型
message = 42; // ❌ 不能将 number 赋给 string
4.2 函数返回值推断
typescript
function multiply(a: number, b: number) {
return a * b; // 推断返回值类型为 number
}
let result = multiply(3, 4); // result 被推断为 number
4.3 最佳通用类型推断
当从多个表达式中推断类型时,TypeScript 会寻找"最佳通用类型":
typescript
let arr = [1, "hello"]; // 推断为 (string | number)[]
4.4 何时依赖推断,何时显式注解?
| 场景 | 推荐做法 | 原因 |
|---|---|---|
| 简单变量初始化 | 依赖推断 | 代码简洁,无歧义 |
| 函数参数 | 必须注解 | 参数无法推断 |
| 函数返回值 | 可选,但推荐显式注解 | 防止实现错误,增强可读性 |
| 复杂对象/联合类型 | 显式注解 | 避免推断过于宽泛 |
| 常量字面量 | 依赖推断 | 值固定,类型明确 |
typescript
// 推荐显式注解返回值的例子
function fetchData(): string {
// 如果这里误写成 return 123,编译器会报错
return "data";
}
五、函数参数的类型注解
5.1 基本参数注解
每个参数都必须注解类型,除非有默认值(此时可推断)。
typescript
function greet(name: string, age: number): string {
return `${name} is ${age} years old.`;
}
5.2 可选参数与默认参数
- 可选参数 :用
?标记,必须放在必需参数之后 - 默认参数:提供默认值后,类型可推断,但也可显式注解
typescript
// 可选参数
function buildName(first: string, last?: string): string {
return last ? `${first} ${last}` : first;
}
// 默认参数(类型可推断)
function multiply(a: number, b: number = 1): number {
return a * b;
}
5.3 剩余参数
剩余参数是数组类型,需要注解为数组类型。
typescript
function sum(base: number, ...numbers: number[]): number {
return base + numbers.reduce((acc, n) => acc + n, 0);
}
六、常见错误与注意事项
6.1 "变量隐式具有 any 类型"
当变量未注解且未初始化时,TypeScript 会推断为 any(如果启用了 noImplicitAny 则会报错)。
typescript
// 在 strict 模式下会报错
let something; // 隐式 any
something = "text";
something = 123; // 无错误,any 关闭了类型检查
解决方法:要么显式注解,要么立即初始化。
6.2 类型不匹配的赋值
typescript
let count: number = 5;
count = "five"; // ❌ Type 'string' is not assignable to type 'number'.
6.3 函数返回值类型不匹配
typescript
function getValue(): string {
return 42; // ❌ 不能将 number 赋给 string
}
6.4 忽略函数返回值类型注解的后果
typescript
// 没有返回值注解,不小心返回了错误类型也可能被推断为联合类型
function getFlag(flag: boolean) {
if (flag) {
return "yes";
}
return 0; // 推断返回值类型为 string | number
}
// 调用处可能意外处理了数字
七、综合示例
typescript
// 用户信息处理
type UserInfo = {
name: string;
age: number;
isActive: boolean;
};
function createUser(name: string, age: number, isActive: boolean): UserInfo {
return { name, age, isActive };
}
function formatUser(user: UserInfo): string {
return `${user.name} (${user.age}) - ${user.isActive ? "Active" : "Inactive"}`;
}
// 类型推断示例
const defaultUser = createUser("Guest", 0, false); // 推断为 UserInfo
let userName = defaultUser.name; // 推断为 string
let userAge = defaultUser.age; // 推断为 number
console.log(formatUser(defaultUser));
八、小结
- 类型注解 :显式指定类型,语法
: 类型 - 三种基础类型 :
string、number、boolean - 类型推断:TypeScript 智能推断类型,减少冗余注解
- 函数参数:必须注解每个参数(除有默认值外)
- 函数返回值:推荐显式注解,增强契约
| 概念 | 语法示例 | 说明 |
|---|---|---|
| 字符串 | let s: string = "hi" |
文本数据 |
| 数字 | let n: number = 42 |
整数、浮点数等 |
| 布尔 | let b: boolean = true |
true/false |
| 类型推断 | let x = "hello" |
x 自动为 string |
| 函数参数 | function f(p: string) {} |
参数必须注解 |
| 函数返回值 | function f(): number {} |
可省略,但推荐 |
觉得文章有帮助?别忘了:
👍 点赞 👍 -- 给我一点鼓励
⭐ 收藏 ⭐ -- 方便以后查看
🔔 关注 🔔 -- 获取更新通知
标签: #TypeScript #类型注解 #基础类型 #学习笔记 #前端开发