TypeScript 是一个强类型的 JavaScript 超集,为 JavaScript 提供了静态类型检查的功能,提高了开发效率和代码质量。下面是一份详细的 TypeScript 进阶教程,涵盖了高级类型、类型操纵工具、高级功能等主题。
1. 高级类型
1.1 交叉类型(Intersection Types)
交叉类型将多个类型合并为一个类型。
type A = { a: string };
type B = { b: number };
type AB = A & B;
const obj: AB = { a: "hello", b: 42 };1.2 联合类型(Union Types)
联合类型允许变量接受多种类型。
type A = string | number;
let value: A = "hello";
value = 42;增强阅读,2.02 交叉类型与联合类型的区别
1.3 类型别名(Type Aliases)
类型别名是一个自定义的类型名称。
type Point = { x: number; y: number; };
const point: Point = { x: 10, y: 20 };1.4 泛型(Generics)
泛型使得函数和类可以与多种类型进行交互。
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<string>("hello"));
console.log(identity<number>(42));2. 类型操纵工具
2.1 映射类型(Mapped Types)
映射类型根据已有类型创建新类型。
type ReadOnly<T> = {
readonly [P in keyof T]: T[P];
}
type Point = { x: number; y: number; };
type ReadOnlyPoint = ReadOnly<Point>;
const point: ReadOnlyPoint = { x: 10, y: 20 };
// point.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.2.2 条件类型(Conditional Types)
条件类型提供了基于条件的类型选择。
type TypeName<T> = T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" : "object";
type T1 = TypeName<string>; // "string"
type T2 = TypeName<42>; // "number"2.3 用例:Partial、Pick、Record
-
Partial: 将类型的所有属性变为可选。
type Partial<T> = { [P in keyof T]?: T[P]; } type Point = { x: number; y: number; }; type PartialPoint = Partial<Point>; const point: PartialPoint = { x: 10 }; -
Pick: 从类型中选择部分属性。
type Pick<T, K extends keyof T> = { [P in K]: T[P]; } type Point = { x: number; y: number; z: number; }; type Point2D = Pick<Point, "x" | "y">; const point2D: Point2D = { x: 10, y: 20 }; -
Record: 构造具有一组属性的类型。
type Record<K extends keyof any, T> = { [P in K]: T; } type Person = "name" | "age"; type PersonInfo = Record<Person, string>; const person: PersonInfo = { name: "John", age: "30" };
3. 高级功能
3.1 类型推断(Type Inference)
TypeScript 在代码的某些地方会自动推断变量的类型。
let x = 3; // number
const y = "hello"; // string3.2 类型守卫(Type Guards)
类型守卫是一些表达式,它们在运行时检查类型。
function isString(value: any): value is string {
return typeof value === 'string';
}
function example(input: string | number) {
if (isString(input)) {
console.log(input.toUpperCase());
} else {
console.log(input.toFixed());
}
}3.3 装饰器(Decorators)
装饰器是一个特殊的声明,可以附加到类的声明、方法、访问器、属性或参数上(实验性特性)。
function log(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 Example {
@log
add(a: number, b: number): number {
return a + b;
}
}
const e = new Example();
e.add(1, 2);3.4 异步编程(Async/Await)
使用 async 和 await 简化异步操作。
async function fetchData(url: string): Promise<any> {
const response = await fetch(url);
const data = await response.json();
return data;
}
fetchData("https://api.example.com/data")
.then(data => console.log(data))
.catch(error => console.error(error));4. 实战项目
4.1 设置项目
创建一个 TypeScript 项目并初始化:
mkdir ts-advanced
cd ts-advanced
bun init
bun add typescript @types/node
npx tsc --init4.2 配置项目公共配置
编辑生成的 tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"module": "CommonJS",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}4.3 编写示例代码
在 src 目录下创建一个 index.ts 文件:
type User = {
id: number;
name: string;
email?: string;
};
const users: User[] = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob", email: "bob@example.com" }
];
function getUser(id: number): User | undefined {
return users.find(user => user.id === id);
}
const user = getUser(1);
console.log(user?.name); // Alice4.4 编译和运行
编译 TypeScript 代码:
npx tsc运行生成的 JavaScript 代码:
node dist/index.js这份教程涵盖了一些 TypeScript 的高级特性和用法,通过这些知识你可以编写更强大、更安全的 TypeScript 代码。希望对你有所帮助!