本文档为 TypeScript 最新版(5.8.3)的使用指南,涵盖核心概念、类型系统、工具配置及高级特性,每项均附详细示例。TypeScript 是一种为 JavaScript 添加静态类型的超集,旨在提升代码健壮性和开发效率。以下内容适用于初学者和高级开发者。
1. 安装与配置
1.1 安装 TypeScript
TypeScript 可以通过 npm 安装,推荐在项目中局部安装以确保版本一致性。
# 全局安装
npm install -g typescript
# 项目局部安装
npm install --save-dev typescript
检查版本:
tsc --version
1.2 配置 tsconfig.json
tsconfig.json
是 TypeScript 的配置文件,控制编译行为。以下是一个推荐的配置示例:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
"esModuleInterop": true,
"skipLibCheck": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
示例:编译项目
tsc
运行 tsc
会根据 tsconfig.json
编译项目,生成 JavaScript 文件到 dist
目录。
2. 基本类型
TypeScript 的核心是静态类型系统,以下是常见基本类型及其用法。
2.1 基本类型(Primitive Types)
包括 string
、number
、boolean
、null
、undefined
等。
let name: string = "Alice";
let age: number = 25;
let isStudent: boolean = true;
let nothing: null = null;
let notDefined: undefined = undefined;
// 示例:类型检查
// name = 123; // 错误:不能将类型“number”分配给类型“string”
2.2 任意类型(Any)
any
类型允许任意值,适合临时禁用类型检查。
let anything: any = "Hello";
anything = 42; // 合法
anything = { name: "Bob" }; // 合法
2.3 未知类型(Unknown)
unknown
是更安全的 any
,需要类型断言或检查。
let value: unknown = "Hello";
if (typeof value === "string") {
console.log(value.toUpperCase()); // 合法
}
// console.log(value.toUpperCase()); // 错误:类型“unknown”上不存在“toUpperCase”
2.4 数组(Arrays)
数组可以通过类型注解定义。
let numbers: number[] = [1, 2, 3];
let strings: Array<string> = ["a", "b", "c"];
// 示例:数组操作
numbers.push(4); // 合法
// numbers.push("5"); // 错误:不能将类型“string”分配给类型“number”
2.5 元组(Tuples)
元组允许定义固定长度和类型的数组。
let tuple: [string, number] = ["Alice", 25];
// tuple[0] = 123; // 错误:不能将类型“number”分配给类型“string”
// tuple.push("Bob"); // 注意:元组允许 push,但可能破坏类型安全
2.6 枚举(Enums)
枚举定义一组命名常量,支持数字和字符串值。
enum Color {
Red = 1,
Green,
Blue,
}
let color: Color = Color.Green; // 2
console.log(Color[2]); // "Green"
// 字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
}
let dir: Direction = Direction.Up; // "UP"
3. 对象类型
3.1 接口(Interfaces)
接口用于描述对象形状。
interface Person {
name: string;
age: number;
isStudent?: boolean; // 可选属性
readonly id: number; // 只读属性
}
let person: Person = {
name: "Alice",
age: 25,
id: 1,
};
// person.id = 2; // 错误:无法分配到“id”,因为它是只读属性
3.2 类型别名(Type Aliases)
类型别名与接口类似,但更灵活,支持联合类型等。
type Point = {
x: number;
y: number;
};
let point: Point = { x: 10, y: 20 };
3.3 联合类型(Union Types)
允许变量具有多种类型。
let id: string | number = "123";
id = 123; // 合法
// id = true; // 错误:不能将类型“boolean”分配给类型“string | number”
3.4 交叉类型(Intersection Types)
组合多个类型。
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
let person: Person = { name: "Alice", age: 25 };
4. 函数
4.1 函数类型
可以为函数参数和返回值指定类型。
function add(a: number, b: number): number {
return a + b;
}
// 函数表达式
let multiply: (x: number, y: number) => number = (x, y) => x * y;
4.2 可选参数与默认值
参数可以是可选的或有默认值。
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Bob", "Hi")); // "Hi, Bob!"
4.3 函数重载
支持定义多个函数签名。
function parse(input: string): string;
function parse(input: number): number;
function parse(input: string | number): string | number {
return input;
}
let str = parse("test"); // string
let num = parse(123); // number
5. 高级类型
5.1 泛型(Generics)
泛型允许创建可重用的类型。
function identity<T>(value: T): T {
return value;
}
let str = identity<string>("Hello"); // string
let num = identity<number>(42); // number
5.2 条件类型(Conditional Types)
根据条件选择类型。
type IsString<T> = T extends string ? "string" : "not string";
type A = IsString<string>; // "string"
type B = IsString<number>; // "not string"
5.3 工具类型(Utility Types)
TypeScript 提供内置工具类型,如 Partial
、Required
等。
interface User {
name: string;
age: number;
}
let partialUser: Partial<User> = { name: "Alice" }; // 部分属性
let requiredUser: Required<User> = { name: "Bob", age: 30 }; // 所有属性必填
5.4 satisfies 运算符(TypeScript 4.9+)
确保类型匹配但保留具体类型。
type Palette = {
[key: string]: string | number[];
};
const palette = {
red: "#FF0000",
blue: [0, 0, 255],
} satisfies Palette;
// palette.red 是 string 类型,而不是 string | number[]
6. 模块与命名空间
6.1 模块(Modules)
支持 ES 模块和 CommonJS。
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// main.ts
import { add } from "./math";
console.log(add(2, 3)); // 5
6.2 命名空间(Namespaces)
用于组织代码,避免命名冲突。
namespace Geometry {
export interface Point {
x: number;
y: number;
}
export function distance(p1: Point, p2: Point): number {
return Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
}
}
let p1: Geometry.Point = { x: 0, y: 0 };
let p2: Geometry.Point = { x: 3, y: 4 };
console.log(Geometry.distance(p1, p2)); // 5
7. 与 JavaScript 互操作
7.1 声明文件(Declaration Files)
为现有 JavaScript 库提供类型定义。
// my-lib.d.ts
declare module "my-lib" {
export function doSomething(value: string): string;
}
// main.ts
import { doSomething } from "my-lib";
let result = doSomething("test"); // 合法
7.2 类型断言(Type Assertions)
强制指定类型。
let value: any = "Hello";
let strLength: number = (value as string).length; // 合法
8. 装饰器(Decorators,实验性功能)
装饰器用于元编程,需在 tsconfig.json
中启用 experimentalDecorators
。
function logged(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${key} with`, args);
return original.apply(this, args);
};
}
class Calculator {
@logged
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3); // 输出:Calling add with [2, 3]
9. 工具与生态
9.1 Visual Studio Code 支持
VS Code 内置 TypeScript 支持,提供智能提示、错误检查等。
// 鼠标悬停即可查看类型信息
let name: string = "Alice";
9.2 ESLint 与 TypeScript
使用 typescript-eslint
增强代码质量。
npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin
// .eslintrc.json
{
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-unused-vars": "error"
}
}
9.3 TypeDoc 生成文档
使用 TypeDoc 生成 TypeScript 项目文档。
npm install --save-dev typedoc
typedoc --out docs src
10. React 与 TypeScript
10.1 函数组件
为 React 函数组件定义 props 类型。
import React from "react";
interface Props {
name: string;
age?: number;
}
const MyComponent: React.FC<Props> = ({ name, age }) => {
return (
<div>
Hello, {name}! {age && `Age: ${age}`}
</div>
);
};
10.2 Hooks
TypeScript 自动推断 Hooks 类型。
import React, { useState, useEffect } from "react";
const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return <button onClick={() => setCount(count + 1)}>Increment</button>;
};
11. Node.js 与 TypeScript
11.1 使用 tsx 运行
使用 tsx
运行 TypeScript 文件。
npm install --save-dev tsx
npx tsx src/index.ts
11.2 配置 tsconfig.json
推荐 Node.js 项目的配置:
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"outDir": "./dist",
"strict": true
}
}
12. 最新特性(TypeScript 5.8)
12.1 改进的类型推断
TypeScript 5.8 增强了类型推断,尤其是在对象解构时。
const { data } = { data: { name: "Alice" } };
console.log(data.name); // 推断为 string
12.2 实验性类型转换
Node.js 支持 --experimental-transform-types
处理非可擦除语法。
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
}
let status: Status = Status.Active; // 合法
13. 调试与错误处理
13.1 错误提示
TypeScript 在编译时捕获类型错误。
let num: number = 42;
// num = "Hello"; // 错误:不能将类型“string”分配给类型“number”
13.2 调试
在 VS Code 中配置 launch.json
调试 TypeScript。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/dist/index.js",
"preLaunchTask": "tsc: build - tsconfig.json"
}
]
}
14. 最佳实践
- 启用严格模式:在
tsconfig.json
中设置"strict": true
。 - 使用类型别名或接口:为复杂类型定义清晰的结构。
- 避免 any:优先使用
unknown
或具体类型。 - 模块化:将代码组织成模块,增强可维护性。
15. 资源与进一步学习
- 官方文档:https://www.typescriptlang.org/docs/
- TypeScript Handbook:https://www.typescriptlang.org/docs/handbook/
- GitHub 仓库:https://github.com/microsoft/TypeScript
- 社区资源:React TypeScript Cheatsheet、TypeDoc