ts 基础知识总结
TypeScript 日常工作笔记
1. 基础类型
1.1 基本类型
解释: TypeScript 提供了比 JavaScript 更丰富的类型系统。
// 基本类型
let str: string = "hello"; // 字符串
let num: number = 42; // 数字
let bool: boolean = true; // 布尔值
let n: null = null; // null
let u: undefined = undefined; // undefined
let sym: symbol = Symbol("id"); // Symbol
let big: bigint = 123n; // BigInt// 数组类型
let arr1: number[] = [1, 2, 3]; // 数字数组
let arr2: Array<string> = ["a", "b"]; // 字符串数组// 元组类型
let tuple: [string, number] = ["张三", 25]; // 固定长度和类型的数组// 枚举类型
enum Color {Red = "RED",Green = "GREEN",Blue = "BLUE"
}
let color: Color = Color.Red;
1.2 对象类型
解释: 对象类型定义了对象的结构和属性类型。
// 对象类型定义
interface Person {name: string;age: number;email?: string; // 可选属性readonly id: number; // 只读属性
}// 使用接口
const person: Person = {name: "张三",age: 25,id: 1
};// 类型别名
type Point = {x: number;y: number;
};// 联合类型
type Status = "pending" | "success" | "error";
let status: Status = "pending";// 交叉类型
type Employee = Person & {department: string;salary: number;
};
1.3 函数类型
解释: TypeScript 可以为函数参数和返回值指定类型。
// 函数类型定义
function add(a: number, b: number): number {return a + b;
}// 箭头函数类型
const multiply: (a: number, b: number) => number = (a, b) => a * b;// 函数接口
interface MathFunc {(a: number, b: number): number;
}// 可选参数和默认参数
function greet(name: string, greeting: string = "Hello"): string {return `${greeting}, ${name}!`;
}// 剩余参数
function sum(...numbers: number[]): number {return numbers.reduce((acc, num) => acc + num, 0);
}// 函数重载
function process(value: string): string;
function process(value: number): number;
function process(value: string | number): string | number {if (typeof value === "string") {return value.toUpperCase();} else {return value * 2;}
}
2. 高级类型
2.1 泛型
解释: 泛型允许创建可重用的组件,这些组件可以处理多种类型。
// 泛型函数
function identity<T>(arg: T): T {return arg;
}const result1 = identity<string>("hello");
const result2 = identity(42); // 类型推断// 泛型接口
interface Container<T> {value: T;getValue(): T;
}// 泛型类
class Queue<T> {private data: T[] = [];push(item: T): void {this.data.push(item);}pop(): T | undefined {return this.data.shift();}
}const stringQueue = new Queue<string>();
stringQueue.push("hello");
2.2 条件类型
解释: 条件类型根据输入类型选择输出类型。
// 基本条件类型
type NonNullable<T> = T extends null | undefined ? never : T;type T1 = NonNullable<string | number | null>; // string | number// 条件类型与 infer
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;type FuncReturnType = ReturnType<() => string>; // string// 映射类型
type Partial<T> = {[P in keyof T]?: T[P];
};type Required<T> = {[P in keyof T]-?: T[P];
};type Readonly<T> = {readonly [P in keyof T]: T[P];
};// 使用示例
interface User {name: string;age: number;email?: string;
}type PartialUser = Partial<User>; // 所有属性变为可选
type RequiredUser = Required<User>; // 所有属性变为必需
type ReadonlyUser = Readonly<User>; // 所有属性变为只读
2.3 工具类型
解释: TypeScript 提供了许多内置的工具类型。
// Pick - 选择部分属性
type UserBasic = Pick<User, 'name' | 'age'>;// Omit - 排除部分属性
type UserWithoutEmail = Omit<User, 'email'>;// Record - 创建键值对类型
type UserRoles = Record<string, string[]>;// Exclude - 排除联合类型中的某些类型
type NonNull = Exclude<string | number | null, null>; // string | number// Extract - 提取联合类型中的某些类型
type StringOrNumber = Extract<string | number | boolean, string | number>; // string | number// Parameters - 获取函数参数类型
type FuncParams = Parameters<(name: string, age: number) => void>; // [string, number]// InstanceType - 获取构造函数实例类型
class Animal {name: string;constructor(name: string) {this.name = name;}
}
type AnimalInstance = InstanceType<typeof Animal>; // Animal
3. 接口与类型
3.1 接口扩展
解释: 接口可以继承和扩展其他接口。
// 基本接口
interface Shape {color: string;
}// 接口扩展
interface Square extends Shape {sideLength: number;
}// 多接口扩展
interface Circle extends Shape {radius: number;
}interface ColoredCircle extends Circle {borderColor: string;
}// 实现接口
class MySquare implements Square {constructor(public color: string, public sideLength: number) {}
}// 接口合并
interface Box {height: number;width: number;
}interface Box {scale: number;
}// 最终 Box 接口包含 height, width, scale 三个属性
3.2 类型别名
解释: 类型别名可以为类型创建新名称。
// 基本类型别名
type Name = string;
type Age = number;
type UserId = string | number;// 联合类型别名
type Status = "loading" | "success" | "error";// 函数类型别名
type EventHandler = (event: Event) => void;
type AsyncFunction<T> = () => Promise<T>;// 对象类型别名
type Point = {x: number;y: number;
};// 映射类型别名
type Optional<T> = {[K in keyof T]?: T[K];
};// 条件类型别名
type IsString<T> = T extends string ? true : false;
4. 类与面向对象
4.1 类定义
解释: TypeScript 的类支持访问修饰符、抽象类等特性。
// 基本类
class Animal {private name: string;protected age: number;public species: string;constructor(name: string, age: number, species: string) {this.name = name;this.age = age;this.species = species;}public makeSound(): void {console.log("Some sound");}protected getInfo(): string {return `${this.name} is ${this.age} years old`;}
}// 继承
class Dog extends Animal {private breed: string;constructor(name: string, age: number, breed: string) {super(name, age, "Dog");this.breed = breed;}public makeSound(): void {console.log("Woof!");}public getBreedInfo(): string {return `${this.getInfo()}, breed: ${this.breed}`;}
}// 抽象类
abstract class Vehicle {abstract start(): void;stop(): void {console.log("Vehicle stopped");}
}class Car extends Vehicle {start(): void {console.log("Car started");}
}
4.2 访问修饰符
解释: TypeScript 提供了三种访问修饰符来控制类成员的可见性。
class Example {public publicField: string = "public"; // 任何地方都可以访问private privateField: string = "private"; // 只能在类内部访问protected protectedField: string = "protected"; // 只能在类内部和子类中访问public publicMethod(): void {console.log(this.privateField); // 可以访问私有成员}private privateMethod(): void {console.log("private method");}protected protectedMethod(): void {console.log("protected method");}
}class SubExample extends Example {public test(): void {console.log(this.publicField); // 可以访问console.log(this.protectedField); // 可以访问// console.log(this.privateField); // 错误:不能访问私有成员}
}
5. 模块与命名空间
5.1 模块导入导出
解释: TypeScript 支持 ES6 模块语法,可以导入导出类型和值。
// math.ts - 导出模块
export interface Point {x: number;y: number;
}export function add(a: number, b: number): number {return a + b;
}export const PI = 3.14159;export default class Calculator {add(a: number, b: number): number {return a + b;}
}// main.ts - 导入模块
import Calculator, { add, PI, Point } from './math';const calc = new Calculator();
const result = calc.add(5, 3);
const point: Point = { x: 10, y: 20 };// 重命名导入
import { add as addNumbers } from './math';// 导入所有内容
import * as MathUtils from './math';
5.2 命名空间
解释: 命名空间提供了一种组织代码的方式,避免全局命名空间污染。
// 基本命名空间
namespace Validation {export interface StringValidator {isValid(s: string): boolean;}export class EmailValidator implements StringValidator {isValid(s: string): boolean {return s.includes('@');}}export class PhoneValidator implements StringValidator {isValid(s: string): boolean {return /^\d{11}$/.test(s);}}
}// 使用命名空间
const emailValidator = new Validation.EmailValidator();
const isValid = emailValidator.isValid("test@example.com");// 嵌套命名空间
namespace Geometry {export namespace Shapes {export class Circle {constructor(public radius: number) {}area(): number {return Math.PI * this.radius ** 2;}}}
}const circle = new Geometry.Shapes.Circle(5);
6. 类型断言与类型守卫
6.1 类型断言
解释: 类型断言告诉 TypeScript 编译器你比它更了解某个值的类型。
// 基本类型断言
let someValue: unknown = "this is a string";
let strLength: number = (someValue as string).length;// 另一种语法
let strLength2: number = (<string>someValue).length;// 非空断言
function processName(name?: string) {console.log(name!.toUpperCase()); // 断言 name 不为 null/undefined
}// 类型断言函数
function isString(value: unknown): value is string {return typeof value === "string";
}function processValue(value: unknown) {if (isString(value)) {console.log(value.toUpperCase()); // TypeScript 知道 value 是 string}
}
6.2 类型守卫
解释: 类型守卫是运行时检查,用于缩小类型范围。
// typeof 类型守卫
function process(value: string | number) {if (typeof value === "string") {return value.toUpperCase();} else {return value.toFixed(2);}
}// instanceof 类型守卫
class Dog {bark() {return "Woof!";}
}class Cat {meow() {return "Meow!";}
}function makeSound(animal: Dog | Cat) {if (animal instanceof Dog) {return animal.bark();} else {return animal.meow();}
}// in 操作符类型守卫
interface Bird {fly(): void;layEggs(): void;
}interface Fish {swim(): void;layEggs(): void;
}function move(animal: Bird | Fish) {if ("fly" in animal) {animal.fly();} else {animal.swim();}
}
7. 实用类型技巧
7.1 条件类型与映射
解释: 结合条件类型和映射类型可以创建强大的类型工具。
// 深度可选
type DeepPartial<T> = {[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};// 深度只读
type DeepReadonly<T> = {readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};// 提取函数参数类型
type Parameters<T> = T extends (...args: infer P) => any ? P : never;// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;// 提取 Promise 类型
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;// 使用示例
interface User {name: string;profile: {age: number;email: string;};
}type PartialUser = DeepPartial<User>;
// 等价于:
// {
// name?: string;
// profile?: {
// age?: number;
// email?: string;
// };
// }
7.2 模板字面量类型
解释: TypeScript 4.1+ 支持模板字面量类型,可以基于字符串字面量创建类型。
// 基本模板字面量类型
type Greeting = "Hello" | "Hi" | "Welcome";
type Name = "World" | "TypeScript" | "Developer";
type GreetingMessage = `${Greeting} ${Name}!`;// 字符串操作类型
type Uppercase<S extends string> = S extends `${infer F}${infer R}`? `${Uppercase<F>}${Uppercase<R>}`: S;type Lowercase<S extends string> = S extends `${infer F}${infer R}`? `${Lowercase<F>}${Lowercase<R>}`: S;// 字符串替换
type Replace<S extends string, From extends string, To extends string> = S extends `${infer Prefix}${From}${infer Suffix}`? `${Prefix}${To}${Suffix}`: S;// 使用示例
type EventName = "click" | "hover" | "focus";
type HandlerName = `on${Capitalize<EventName>}`;
// 结果: "onClick" | "onHover" | "onFocus"
8. 错误处理与调试
8.1 严格模式
解释: TypeScript 的严格模式可以帮助捕获更多潜在错误。
// tsconfig.json 中的严格选项
{"compilerOptions": {"strict": true, // 启用所有严格检查"noImplicitAny": true, // 禁止隐式 any"strictNullChecks": true, // 严格的 null 检查"strictFunctionTypes": true, // 严格的函数类型检查"strictBindCallApply": true, // 严格的 bind/call/apply 检查"strictPropertyInitialization": true, // 严格的属性初始化检查"noImplicitReturns": true, // 禁止隐式返回"noFallthroughCasesInSwitch": true, // 禁止 switch 中的 fallthrough"noUncheckedIndexedAccess": true // 禁止未检查的索引访问}
}// 严格 null 检查示例
function processName(name: string | null) {if (name === null) {return "Anonymous";}return name.toUpperCase(); // TypeScript 知道 name 不是 null
}
8.2 类型错误处理
解释: 处理 TypeScript 编译错误的最佳实践。
// 使用类型断言处理第三方库
declare const externalLib: any;
const data = externalLib.getData() as MyDataType;// 使用 unknown 类型
function processUnknownData(data: unknown) {if (typeof data === "object" && data !== null) {const obj = data as Record<string, unknown>;if ("name" in obj && typeof obj.name === "string") {console.log(obj.name.toUpperCase());}}
}// 使用 satisfies 操作符(TypeScript 4.9+)
const config = {apiUrl: "https://api.example.com",timeout: 5000,retries: 3
} satisfies ApiConfig;// 使用 const 断言
const colors = ["red", "green", "blue"] as const;
type Color = typeof colors[number]; // "red" | "green" | "blue"
9. 项目实践
9.1 类型定义文件
解释: 为第三方库或项目创建类型定义。
// types/global.d.ts
declare global {interface Window {myCustomProperty: string;}namespace NodeJS {interface ProcessEnv {NODE_ENV: "development" | "production" | "test";API_URL: string;}}
}export {};// types/api.d.ts
export interface ApiResponse<T = any> {success: boolean;data: T;message: string;code: number;
}export interface PaginatedResponse<T> extends ApiResponse<T[]> {pagination: {page: number;pageSize: number;total: number;totalPages: number;};
}// types/user.d.ts
export interface User {id: number;name: string;email: string;avatar?: string;createdAt: string;updatedAt: string;
}export interface CreateUserRequest {name: string;email: string;password: string;
}export interface UpdateUserRequest extends Partial<CreateUserRequest> {id: number;
}
9.2 实用工具类型
解释: 创建项目中常用的工具类型。
// utils/types.ts
// 提取 API 响应类型
type ApiResponseType<T> = T extends Promise<ApiResponse<infer U>> ? U : never;// 提取表单字段类型
type FormFields<T> = {[K in keyof T]: T[K] extends string | number | boolean ? T[K] : never;
};// 创建表单验证规则类型
type ValidationRules<T> = {[K in keyof T]?: {required?: boolean;min?: number;max?: number;pattern?: RegExp;message?: string;};
};// 提取事件处理函数类型
type EventHandler<T> = (event: T) => void;// 创建状态类型
type LoadingState = "idle" | "loading" | "success" | "error";type StateWithLoading<T> = {data: T | null;loading: LoadingState;error: string | null;
};// 使用示例
interface UserForm {name: string;email: string;age: number;
}type UserFormFields = FormFields<UserForm>;
type UserValidationRules = ValidationRules<UserForm>;
10. 常见问题与解决方案
10.1 类型推断问题
// 问题:类型推断不准确
const items = [1, 2, 3, "hello"]; // 推断为 (number | string)[]// 解决方案:明确类型
const items: number[] = [1, 2, 3];
const mixedItems: (number | string)[] = [1, 2, 3, "hello"];
10.2 泛型约束
// 问题:泛型类型过于宽泛
function getProperty<T>(obj: T, key: string) {return obj[key]; // 错误:不能保证 key 存在于 obj 中
}// 解决方案:添加约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {return obj[key];
}
10.3 异步函数类型
// 问题:异步函数返回类型不明确
async function fetchData() {const response = await fetch('/api/data');return response.json(); // 返回 any
}// 解决方案:明确返回类型
async function fetchData(): Promise<User[]> {const response = await fetch('/api/data');return response.json();
}
本笔记涵盖了 TypeScript 的核心概念和实用技巧,适合日常开发查阅。建议结合官方文档和实际项目实践深入学习。