TypeScript 开发指南 / 03 - 基本类型
基本类型
类型系统概览
TypeScript 的类型系统分为两大类:
| 类别 | 包含类型 | 说明 |
|---|---|---|
| 原始类型(Primitive) | string, number, boolean, null, undefined, symbol, bigint | 不可变的基础值 |
| 引用类型(Reference) | object, array, tuple, enum, function, class | 可变的复合结构 |
| 特殊类型 | any, unknown, never, void | 用于特定场景 |
| 高级类型 | 联合、交叉、字面量、泛型等 | 后续章节详述 |
原始类型(Primitive Types)
string(字符串)
// 字符串类型注解
const name: string = "Alice";
const greeting: string = `Hello, ${name}!`; // 模板字符串也支持
// 多行字符串
const html: string = `
<div>
<h1>${name}</h1>
</div>
`;
number(数字)
TypeScript 的 number 类型包含整数和浮点数,也支持特殊数值:
const age: number = 25;
const price: number = 99.99;
const hex: number = 0xff; // 十六进制
const binary: number = 0b1010; // 二进制
const octal: number = 0o744; // 八进制
const million: number = 1_000_000; // 数字分隔符(ES2021)
// 特殊值
const notANumber: number = NaN;
const infinity: number = Infinity;
注意:TypeScript 没有专门的
integer类型,所有数字都是 IEEE 754 双精度浮点数。
boolean(布尔值)
const isActive: boolean = true;
const isDeleted: boolean = false;
// 逻辑运算
const result: boolean = isActive && !isDeleted;
null 和 undefined
const nothing: null = null;
const notDefined: undefined = undefined;
// 在 strictNullChecks 模式下,null 和 undefined 是独立类型
// 不能赋值给其他类型
const name: string = null; // ❌ 错误(strictNullChecks: true)
const name: string | null = null; // ✅ 正确
| 值 | typeof | 说明 |
|---|---|---|
null | "object" | 表示"无值" |
undefined | "undefined" | 表示"未定义" |
symbol(符号)
const id: symbol = Symbol("id");
const anotherId: symbol = Symbol("id");
// 每个 Symbol 都是唯一的
console.log(id === anotherId); // false
// 用作对象属性键
const user = {
[id]: 12345,
name: "Alice"
};
console.log(user[id]); // 12345
bigint(大整数)
// ES2020 引入,用于表示任意精度整数
const largeNumber: bigint = 9007199254740991n;
const anotherBig: bigint = BigInt(9007199254740991);
// 不能与 number 混合运算
const sum = largeNumber + 10; // ❌ 错误
const sum = largeNumber + 10n; // ✅ 正确
类型注解(Type Annotation)
类型注解使用冒号 : 语法显式声明变量的类型:
// 变量声明
const name: string = "Alice";
let age: number = 25;
const isActive: boolean = true;
// 数组声明
const numbers: number[] = [1, 2, 3];
const names: Array<string> = ["Alice", "Bob"]; // 泛型语法
// 对象声明
const user: { name: string; age: number } = {
name: "Alice",
age: 25
};
注解的位置
// 变量注解
let count: number = 0;
// 函数参数注解
function greet(name: string): string {
return `Hello, ${name}!`;
}
// 函数返回值注解
function add(a: number, b: number): number {
return a + b;
}
// 类型注解是可选的——TypeScript 可以推断类型
let count = 0; // TypeScript 推断为 number 类型
类型推断(Type Inference)
TypeScript 的类型推断引擎非常强大,在大多数情况下不需要显式注解:
// TypeScript 自动推断类型
let name = "Alice"; // 推断为 string
let age = 25; // 推断为 number
let isActive = true; // 推断为 boolean
let items = [1, 2, 3]; // 推断为 number[]
let user = { // 推断为 { name: string; age: number }
name: "Alice",
age: 25
};
// 函数返回值也会被推断
function add(a: number, b: number) {
return a + b; // 推断返回值为 number
}
何时需要显式注解?
| 场景 | 是否需要注解 | 示例 |
|---|---|---|
| 变量有初始值 | 通常不需要 | let x = 10 |
| 函数参数 | 必须注解 | function f(x: number) |
| 函数返回值 | 建议注解 | function f(): number |
| 空数组 | 需要注解 | let arr: number[] = [] |
null 初始值 | 需要注解 | let el: HTMLElement | null = null |
| 复杂对象 | 建议注解或使用接口 | 见第 5 章 |
// 空数组需要注解
let items = []; // 推断为 any[](不推荐)
let items: number[] = []; // ✅ 明确类型
// null 初始值需要注解
let element = null; // 推断为 any
let element: HTMLElement | null = null; // ✅ 明确类型
// 函数参数必须注解
function multiply(a, b) { // ❌ 隐式 any(noImplicitAny: true 时报错)
return a * b;
}
function multiply(a: number, b: number) { // ✅
return a * b;
}
特殊类型
any(任意类型)
any 类型会绕过类型检查,应尽量避免使用:
// any 允许任何操作
let value: any = "hello";
value = 42; // ✅
value.foo(); // ✅(编译不报错,但运行时可能出错)
value = true; // ✅
// 什么时候可以使用 any?
// 1. 迁移旧代码时临时使用
// 2. 第三方库没有类型定义时
// 3. 处理动态数据(如 JSON.parse)
const data: any = JSON.parse('{"name": "Alice"}');
注意:在
strict模式下,应尽量用unknown替代any。
unknown(未知类型)
unknown 是类型安全的 any,使用前必须进行类型检查:
let value: unknown = "hello";
// 不能直接使用
value.toUpperCase(); // ❌ 错误:类型 "unknown" 上不存在属性 "toUpperCase"
// 必须先进行类型检查
if (typeof value === "string") {
console.log(value.toUpperCase()); // ✅ 类型收窄为 string
}
// 或使用类型断言
console.log((value as string).toUpperCase()); // ✅
| 特性 | any | unknown |
|---|---|---|
| 可以赋值给其他类型 | ✅ | ❌ |
| 可以调用方法 | ✅ | ❌(需先检查) |
| 类型安全 | ❌ | ✅ |
| 使用场景 | 临时兼容 | 安全的动态类型 |
void
void 表示函数没有返回值:
function logMessage(message: string): void {
console.log(message);
// 没有 return 语句,或 return;
}
// void 变量(通常不常用)
let unusable: void = undefined;
never
never 表示永远不会发生的类型:
// 抛出异常的函数
function throwError(message: string): never {
throw new Error(message);
}
// 无限循环
function infiniteLoop(): never {
while (true) {}
}
// 穷尽检查
type Shape = "circle" | "square" | "triangle";
function getArea(shape: Shape): number {
switch (shape) {
case "circle":
return Math.PI * 10 ** 2;
case "square":
return 10 * 10;
case "triangle":
return 0.5 * 10 * 10;
default:
const _exhaustive: never = shape; // 如果遗漏了某个 case,这里会报错
return _exhaustive;
}
}
object
object 类型表示非原始类型的值:
// object 类型
const person: object = { name: "Alice" };
const arr: object = [1, 2, 3];
// 更推荐使用具体的对象类型
const person: { name: string; age: number } = {
name: "Alice",
age: 25
};
类型断言(Type Assertion)
当你比 TypeScript 更了解某个值的类型时,可以使用类型断言:
// as 语法(推荐)
const input = document.getElementById("myInput") as HTMLInputElement;
input.value = "Hello";
// 尖括号语法(JSX 中不能使用)
const input = <HTMLInputElement>document.getElementById("myInput");
// 双重断言(极端情况,不推荐)
const value = "hello" as any as number; // 编译通过,但逻辑上错误
注意:类型断言不进行运行时转换,它只是告诉编译器"相信我,我知道这个值的类型"。
常见的内置对象类型
TypeScript 内置了许多常用的对象类型:
// 日期
const now: Date = new Date();
// 正则表达式
const pattern: RegExp = /hello/gi;
// 错误
const error: Error = new Error("Something went wrong");
// Promise
const promise: Promise<string> = new Promise((resolve) => {
resolve("done");
});
// Map 和 Set
const map: Map<string, number> = new Map();
map.set("age", 25);
const set: Set<number> = new Set([1, 2, 3]);
业务场景:表单数据类型定义
// 定义表单数据接口
interface LoginForm {
username: string;
password: string;
rememberMe: boolean;
}
interface RegistrationForm extends LoginForm {
email: string;
age: number;
agreeToTerms: boolean;
}
// 表单验证函数
function validateLogin(form: LoginForm): string[] {
const errors: string[] = [];
if (form.username.length < 3) {
errors.push("用户名至少 3 个字符");
}
if (form.password.length < 8) {
errors.push("密码至少 8 个字符");
}
return errors;
}
// 使用
const form: LoginForm = {
username: "alice",
password: "12345678",
rememberMe: true
};
const errors = validateLogin(form);
if (errors.length === 0) {
console.log("验证通过");
} else {
console.log("验证失败:", errors);
}
类型兼容性速查
// 原始类型:值相等即可
let a: string = "hello";
let b: string = a; // ✅
// 对象类型:结构兼容(鸭子类型)
interface Point {
x: number;
y: number;
}
const point3D = { x: 1, y: 2, z: 3 };
const point2D: Point = point3D; // ✅ 多余属性兼容
// 函数类型:参数和返回值兼容
type Handler = (a: number) => void;
const handler: Handler = (a: number, b?: number) => {}; // ✅