TypeScript 基础类型
TypeScript 的类型系统是其核心特性,理解基础类型是掌握 TypeScript 的第一步。
原始类型
TypeScript 支持 JavaScript 的所有原始类型,并提供类型注解。
基本原始类型
// 字符串
let name: string = "TypeScript";
// 数字(整数和浮点数统一为 number)
let age: number = 25;
let price: number = 99.99;
// 布尔值
let isActive: boolean = true;
// BigInt(ES2020+)
let bigNumber: bigint = 100n;
// Symbol
let sym: symbol = Symbol("key");null 和 undefined
// 默认情况下,null 和 undefined 是所有类型的子类型
let u: undefined = undefined;
let n: null = null;
// 开启 strictNullChecks 后,需要显式处理
let value: string | null = null;
value = "hello";数组类型
两种定义数组的方式:
// 方式一:类型[]
let numbers: number[] = [1, 2, 3];
let names: string[] = ["Alice", "Bob"];
// 方式二:Array<类型>(泛型语法)
let scores: Array<number> = [100, 95, 88];
// 只读数组
let readonlyArr: readonly number[] = [1, 2, 3];
// readonlyArr.push(4); // 错误:只读数组不能修改元组(Tuple)
元组是固定长度和类型的数组。
// 基本元组
let tuple: [string, number] = ["hello", 42];
// 访问元素
console.log(tuple[0]); // "hello"
console.log(tuple[1]); // 42
// 可选元素
let optionalTuple: [string, number?] = ["hello"];
// 剩余元素
let restTuple: [string, ...number[]] = ["hello", 1, 2, 3];
// 只读元组
let readonlyTuple: readonly [string, number] = ["hello", 42];
// 命名元组(TypeScript 4.0+)
type NamedTuple = [name: string, age: number];
let person: NamedTuple = ["Alice", 25];枚举(Enum)
枚举用于定义一组命名常量。
数字枚举
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
// 使用
let dir: Direction = Direction.Up;
// 可以指定起始值
enum Status {
Pending = 1,
Active, // 2
Completed // 3
}字符串枚举
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
let color: Color = Color.Red;
console.log(color); // "RED"const 枚举
编译时会被内联,不生成额外代码:
const enum HttpStatus {
OK = 200,
NotFound = 404,
ServerError = 500
}
let status = HttpStatus.OK; // 编译后直接变成 200特殊类型
any
放弃类型检查,谨慎使用:
let anything: any = 42;
anything = "hello";
anything = true;
anything.foo.bar; // 不会报错,但运行时可能出错unknown
类型安全的 any,使用前必须进行类型检查:
let value: unknown = "hello";
// 直接使用会报错
// console.log(value.length); // 错误
// 必须先检查类型
if (typeof value === "string") {
console.log(value.length); // 正确
}
// 或使用类型断言
console.log((value as string).length);void
表示没有返回值:
function log(message: string): void {
console.log(message);
}
// void 类型变量只能赋值 undefined
let v: void = undefined;never
表示永不返回的类型:
// 抛出异常
function throwError(message: string): never {
throw new Error(message);
}
// 无限循环
function infiniteLoop(): never {
while (true) {}
}
// 用于穷尽检查
type Shape = "circle" | "square";
function getArea(shape: Shape): number {
switch (shape) {
case "circle":
return Math.PI * 10 * 10;
case "square":
return 10 * 10;
default:
const _exhaustive: never = shape;
return _exhaustive;
}
}对象类型
object 类型
表示非原始类型:
let obj: object = { name: "Alice" };
obj = [1, 2, 3]; // 数组也是对象
// obj = "hello"; // 错误:string 不是 object对象字面量类型
let user: { name: string; age: number } = {
name: "Alice",
age: 25
};
// 可选属性
let config: { url: string; timeout?: number } = {
url: "https://api.example.com"
};
// 只读属性
let point: { readonly x: number; readonly y: number } = {
x: 10,
y: 20
};
// point.x = 30; // 错误:只读属性不能修改字面量类型
// 字符串字面量
let direction: "left" | "right" = "left";
// 数字字面量
let dice: 1 | 2 | 3 | 4 | 5 | 6 = 3;
// 布尔字面量
let success: true = true;
// 结合使用
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
function request(url: string, method: HttpMethod) {
// ...
}类型断言
告诉编译器你比它更了解类型:
// 方式一:as 语法(推荐)
let value: unknown = "hello";
let length = (value as string).length;
// 方式二:尖括号语法(JSX 中不可用)
let length2 = (<string>value).length;
// 双重断言(谨慎使用)
let num = "hello" as unknown as number;
// const 断言
let arr = [1, 2, 3] as const; // readonly [1, 2, 3]
let obj = { name: "Alice" } as const; // { readonly name: "Alice" }最佳实践
- 优先使用
unknown而非any:保持类型安全 - 避免过度使用类型断言:让 TypeScript 自动推断
- 使用
const枚举:减少运行时开销 - 启用
strictNullChecks:避免空值错误 - 使用字面量类型:提供更精确的类型约束