TypeScript 编程学习笔记

1. 变量与常量

TypeScript 支持 let 声明变量和 const 声明常量。

let age: number = 30;
const name: string = "Alice";

注意事项: const 声明的变量不可重新赋值,类型必须在声明时确定。

2. 数据类型

TypeScript 是强类型语言,支持基本数据类型(numberstringboolean)、数组、元组等。

let isStudent: boolean = true;
let scores: number[] = [90, 85, 88];
let user: [string, number] = ["Alice", 30];

易错点:元组类型严格限制每个元素的类型和顺序,使用时需准确匹配。

3. 条件语句

TypeScript 支持 ifelseswitch 语句,与 JavaScript 相似。

if (age > 18) {
    console.log("Adult");
} else {
    console.log("Minor");
}

注意事项:注意条件语句中使用类型转换,以确保表达式返回布尔值。

4. 函数

TypeScript 使用 function 定义函数,支持可选参数和默认参数。

function greet(name: string, age: number = 30): string {
    return `Hello, ${name}. You are ${age} years old.`;
}

易错点:可选参数必须放在参数列表末尾,否则会引发错误。

5. 接口

接口定义对象的结构,用于描述对象的属性和方法。

interface Person {
    name: string;
    age: number;
}

let user: Person = { name: "Alice", age: 30 };

注意事项:接口属性默认是必选的,使用 ? 标记为可选属性。

6. 类

TypeScript 中的类支持继承、多态和访问控制符(publicprotectedprivate)。

class Person {
    public name: string;
    private age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet(): void {
        console.log(`Hello, ${this.name}`);
    }
}

易错点: private 属性只能在类内部访问,避免跨类调用。

7. 泛型

泛型使代码更具通用性,允许在类、接口和函数中使用类型参数。

function identity(arg: T): T {
    return arg;
}

console.log(identity(42));

注意事项:泛型参数可用于函数签名和返回类型,但使用时必须指定具体类型。

8. 类型断言

类型断言用于告诉编译器将变量视为特定类型,常用于类型检查。

let someValue: any = "Hello, TypeScript";
let strLength: number = (someValue as string).length;

易错点:避免错误的类型断言,以防运行时错误。

9. 模块化

TypeScript 支持 importexport 模块化,用于组织代码。

// 在 module.ts 中
export const PI = 3.14;

// 在 main.ts 中
import { PI } from './module';

注意事项:确保模块路径正确,否则会导致导入失败。

10. 装饰器

装饰器用于修改类、方法或属性,通常用于元数据注入。

function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function(...args: any[]) {
        console.log(`Calling ${propertyKey} with`, args);
        return originalMethod.apply(this, args);
    };
    return descriptor;
}

class Person {
    @log
    greet(message: string): void {
        console.log(message);
    }
}

易错点:装饰器仅在实验性阶段,需在 tsconfig.json 中启用。

高级与小众用法

联合类型和类型保护

联合类型允许变量拥有多种可能的类型,类型保护用于检查类型。

function printId(id: string | number) {
    if (typeof id === "string") {
        console.log(`ID: ${id.toUpperCase()}`);
    } else {
        console.log(`ID: ${id}`);
    }
}

注意事项:使用 typeofinstanceof 进行类型保护。

交叉类型

交叉类型用于合并多个类型的属性。

type Admin = { name: string; privileges: string[] };
type Employee = { name: string; startDate: Date };
type ElevatedEmployee = Admin & Employee;

易错点:交叉类型要求对象必须包含所有属性,适合定义复合类型。

字面量类型

字面量类型用于定义固定值。

type Direction = "up" | "down";
let move: Direction = "up";

注意事项:字面量类型可以与联合类型结合,限制变量取值范围。

可辨识联合类型

使用联合类型的可辨识属性进行类型判断。

interface Circle {
    kind: "circle";
    radius: number;
}

interface Square {
    kind: "square";
    sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape) {
    switch (shape.kind) {
        case "circle":
            return Math.PI * shape.radius ** 2;
        case "square":
            return shape.sideLength ** 2;
    }
}

注意事项:确保每个联合类型有唯一的标识,以实现类型推断。

键入映射类型

映射类型允许根据已有类型定义新的类型。

type Optional = { [P in keyof T]?: T[P] };
type Person = { name: string; age: number };
type PartialPerson = Optional<Person>;

易错点:映射类型中保持一致性,避免重复定义属性。