跳转至

TypeScript 高级类型

TypeScript 是 JavaScript 的超集,通过类型系统在编译时捕获错误,高级类型系统(泛型、联合类型、映射类型等)能让代码更安全、更易维护,是现代前端和 Node.js 开发的标配。

核心知识点

知识点说明
语言类型JavaScript 的静态类型超集
最新版本TypeScript 5.7+
核心优势编译时类型检查、IDE 智能提示、重构安全
运行方式编译为 JavaScript 后运行
高级特性泛型、联合类型、交叉类型、映射类型、条件类型

安装配置

npm install -g typescript       # 全局安装 TypeScript
tsc --version                    # 查看版本

# 初始化 TypeScript 项目
tsc --init                       # 生成 tsconfig.json

基本使用

1. 基础类型

// 基本类型
let name: string = "TypeScript";      // 字符串
let age: number = 25;                  // 数字
let isDone: boolean = false;           // 布尔
let scores: number[] = [8, 9, 7];     // 数组
let pair: [string, number] = ["TP53", 8.5];  // 元组

// 接口(定义对象结构)
interface Sample {
    id: string;                        // 必需属性
    diagnosis: string;
    bmi?: number;                      // 可选属性(?)
    readonly created_at: string;       // 只读属性
}

const sample: Sample = {
    id: "T2D_001",
    diagnosis: "T2D",
    bmi: 28.5,
    created_at: "2025-01-01"
};

2. 联合类型和类型守卫

// 联合类型:值可以是多种类型之一
type DiagnosisResult = string | number | null;

function formatResult(result: DiagnosisResult): string {
    if (typeof result === "string") {      // 类型守卫
        return result.toUpperCase();
    } else if (typeof result === "number") {
        return result.toFixed(2);
    }
    return "N/A";
}

// 字面量类型
type Diagnosis = "T2D" | "Healthy" | "Prediabetes";  // 只允许这三个值
let d: Diagnosis = "T2D";              // OK
// let d2: Diagnosis = "Other";        // 编译错误!

3. 泛型

// 泛型函数
function getFirst<T>(arr: T[]): T | undefined {  // T 是类型参数
    return arr[0];
}

const num = getFirst([1, 2, 3]);        // 自动推断为 number
const str = getFirst(["a", "b"]);       // 自动推断为 string

// 泛型接口
interface ApiResponse<T> {
    data: T;
    status: number;
    message: string;
}

// 使用泛型接口
const response: ApiResponse<Sample[]> = {
    data: [{ id: "T2D_001", diagnosis: "T2D", created_at: "2025-01-01" }],
    status: 200,
    message: "success"
};

// 泛型约束
interface HasId { id: string; }

function findById<T extends HasId>(items: T[], id: string): T | undefined {
    return items.find(item => item.id === id);  // T 必须有 id 属性
}

高级用法

1. 映射类型和工具类型

// 内置工具类型
type PartialSample = Partial<Sample>;    // 所有属性变可选
type RequiredSample = Required<Sample>;  // 所有属性变必需
type ReadonlySample = Readonly<Sample>;  // 所有属性变只读
type PickedSample = Pick<Sample, "id" | "diagnosis">;  // 选取部分属性
type OmittedSample = Omit<Sample, "bmi">;  // 排除部分属性

// Record 类型
type GeneExpression = Record<string, number>;  // { [key: string]: number }
const expression: GeneExpression = {
    "TP53": 8.5,
    "BRCA1": 6.2,
    "EGFR": 9.1
};

2. 条件类型

// 条件类型
type IsString<T> = T extends string ? "是字符串" : "不是字符串";
type A = IsString<string>;   // "是字符串"
type B = IsString<number>;   // "不是字符串"

// 实用的条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
type ExtractString<T> = T extends string ? T : never;

3. 类型推断(infer)

// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function analyze(): { gene: string; score: number } {
    return { gene: "TP53", score: 0.95 };
}

type AnalysisResult = ReturnType<typeof analyze>;
// { gene: string; score: number }

常见报错与解决

报错信息原因解决方法
Type X is not assignable to type Y类型不匹配检查类型定义或用类型断言
Property does not exist on type访问不存在的属性检查接口定义或用可选链 ?.
Object is possibly undefined可能是 undefined!(断言非空)或 ?.(可选链)
Generic type requires type arguments泛型需要类型参数提供类型参数 <Type>

速查表

// ===== TypeScript 高级类型速查表 =====

// 联合 & 交叉
type A = string | number;              // 联合:A 或 B
type B = TypeA & TypeB;                // 交叉:A 且 B

// 工具类型
Partial<T>      // 全部可选
Required<T>     // 全部必需
Readonly<T>     // 全部只读
Pick<T, K>      // 选取属性
Omit<T, K>      // 排除属性
Record<K, V>    // 键值对类型
Exclude<T, U>   // 排除类型
Extract<T, U>   // 提取类型
NonNullable<T>  // 排除 null/undefined
ReturnType<T>   // 函数返回类型
Parameters<T>   // 函数参数类型

// 泛型
function f<T>(x: T): T { return x; }
interface I<T> { data: T; }
class C<T> { value: T; }

// 类型守卫
typeof x === "string"
x instanceof Class
"prop" in obj

// 类型断言
value as Type
value!                // 非空断言