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"; // string

3.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)

使用 asyncawait 简化异步操作。

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 --init

4.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);  // Alice

4.4 编译和运行

编译 TypeScript 代码:

npx tsc

运行生成的 JavaScript 代码:

node dist/index.js

这份教程涵盖了一些 TypeScript 的高级特性和用法,通过这些知识你可以编写更强大、更安全的 TypeScript 代码。希望对你有所帮助!