TypeScript 语言

精选 TypeScript 核心类型系统、接口 Interface、泛型 Generics、类与访问修饰符、高级类型工具及条件类型的全量备忘单。

#🚀 入门指引

#安装 TypeScript 编译器 (Installing the Compiler)

npm install typescript --save-dev
npx tsc

#入门介绍

TypeScript 是 JavaScript 的强类型超集,为 JS 增加了静态类型检查接口 (Interface) 以及编译期错误捕获。它最终会编译转换为纯粹的 JavaScript。

#基础数据类型 (Basic Types)

let age: number = 25;
let name: string = "Alice";
let isOnline: boolean = true;
let notSure: any = "可以是任意类型";
let nothingHere: null = null;
let notDefined: undefined = undefined;
let symbolValue: symbol = Symbol("unique");
let bigIntValue: bigint = 9007199254740991n;

#数组类型

let numbers: number[] = [1, 2, 3];
let fruits: Array<string> = ["apple", "banana"];
let mixed: (string | number)[] = ["one", 2, "three"];

#元组 (Tuples)

let person: [string, number];
person = ["John", 30]; // ✅ 类型与顺序完全对应
person = [30, "John"]; // ❌ 编译报错:类型不匹配

#枚举 (Enums)

enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

let move: Direction = Direction.Up;

enum Status {
  Success = "SUCCESS",
  Error = "ERROR"
}

#类型别名 (Type Aliases)

type ID = string | number;
let userId: ID = 123;

type Callback = () => void;

#接口声明 (Interfaces)

interface User {
  name: string;
  age: number;
  isAdmin?: boolean; // 可选属性
  readonly id: number; // 只读属性
}

const user: User = { name: "Bob", age: 25, id: 1 };

#接口继承与扩展 (Extending Interfaces)

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;
}

const dog: Dog = { name: "Fido", breed: "Labrador" };

#函数类型定义 (Functions)

function greet(name: string): string {
  return `Hello, ${name}`;
}

const add = (a: number, b: number): number => a + b;

#可选参数与默认参数 (可选 & Default Parameters)

function log(message: string, userId?: string) {
  console.log(message, userId ?? "Guest");
}

function multiply(a: number, b: number = 2) {
  return a * b;
}

#剩余参数 (Rest Parameters)

function sum(...numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

#函数重载 (Function Overloads)

function combine(a: number, b: number): number;
function combine(a: string, b: string): string;
function combine(a: any, b: any): any {
  return a + b;
}

#联合类型与交叉类型 (Union & Intersection Types)

type Status = "success" | "error" | "loading";

type UserInfo = { name: string };
type AdminInfo = { admin: boolean };

type AdminUser = UserInfo & AdminInfo;

#字面量类型 (Literal Types)

type Alignment = "left" | "center" | "right";
let align: Alignment = "left";

#泛型基础 (Generics)

function identity<T>(value: T): T {
  return value;
}

let num = identity<number>(42);
let str = identity("Hello");

#泛型约束 (Generic Constraints)

interface Lengthwise {
  length: number;
}

function logLength<T extends Lengthwise>(arg: T): void {
  console.log(arg.length);
}

#泛型接口 (Generic Interfaces)

interface GenericIdentityFn<T> {
  (arg: T): T;
}

const myIdentity: GenericIdentityFn<number> = identity;

#类定义 (Classes)

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

const alice = new Person("Alice");
alice.greet();

#访问修饰符 (Access Modifiers)

class Car {
  public brand: string;
  private speed: number;
  protected year: number;

  constructor(brand: string, speed: number, year: number) {
    this.brand = brand;
    this.speed = speed;
    this.year = year;
  }
}

#抽象类 (Abstract Classes)

abstract class Animal {
  abstract makeSound(): void;
  move(): void {
    console.log("Moving...");
  }
}

class Dog extends Animal {
  makeSound() {
    console.log("Woof!");
  }
}

#接口实现 (Implements Interface)

interface Vehicle {
  start(): void;
}

class Bike implements Vehicle {
  start() {
    console.log("Bike starting...");
  }
}

#类型断言 (Type Assertions)

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

#空值合并运算符 (Nullish Coalescing)

let input: string | null = null;
let result = input ?? "Default";

#可选链运算符 (可选 Chaining)

const user = { profile: { name: "Alice" } };
console.log(user.profile?.name); // Alice
console.log(user.address?.street); // undefined

#命名空间 (Namespaces)

namespace Utils {
  export function log(msg: string) {
    console.log(msg);
  }
}

Utils.log("Hello");

#模块导入导出 (Modules)

// math.ts
export function add(a: number, b: number) {
  return a + b;
}

// app.ts
import { add } from "./math";
console.log(add(2, 3));

#默认导出 (Export Default)

// logger.ts
export default class Logger {
  log(msg: string) {
    console.log(msg);
  }
}

// main.ts
import Logger from "./logger";
const logger = new Logger();
logger.log("Info");

#Promise 与 Async/Await

async function fetchData(): Promise<string> {
  return "Data loaded";
}

fetchData().then(console.log);

#异步函数类型标注 (Typing Async Functions)

interface User {
  id: number;
  name: string;
}

async function getUser(id: number): Promise<User> {
  // 模拟异步获取数据
  return { id, name: "User" };
}

#Readonly 与 Record 内置工具类型

interface Config {
  readonly apiKey: string;
}

type Point = Record<"x" | "y", number>;
const origin: Point = { x: 0, y: 0 };

#⚡ 高级特性与技巧 (Features)

#类型守卫与谓词 (Type Guards)

function isString(value: any): value is string {
  return typeof value === "string";
}

function process(value: string | number) {
  if (isString(value)) {
    console.log(value.toUpperCase());
  } else {
    console.log(value.toFixed(2));
  }
}

#索引签名 (Index Signatures)

interface Dictionary {
  [key: string]: string;
}

const dict: Dictionary = { hello: "world" };

#映射类型 (Mapped Types)

type Flags = { [K in "option1" | "option2"]: boolean };
const flags: Flags = { option1: true, option2: false };

#条件类型 (Conditional Types)

type NonNullable<T> = T extends null | undefined ? never : T;
type SafeString = NonNullable<string | null>; // 解析为 string

#unknown 与 any 类型对比

let value: unknown;
value = 5; // 合法
// console.log(value.length); // 报错:必须先经过类型收窄或断言

let anyValue: any;
anyValue = 5;
console.log(anyValue.length); // 不会抛出类型错误,但运行时存在风险

#Never 类型 (Never Type)

function throwError(msg: string): never {
  throw new Error(msg);
}

#装饰器 (Decorators)

function sealed(target: any) {
  Object.seal(target);
  Object.seal(target.prototype);
}

@sealed
class SealedClass {}

#内置工具类型 (Utility Types)

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

// Partial: 将属性全部变为可选
type PartialTodo = Partial<Todo>;

// 必填: 将属性全部变为必填
type 必填Todo = 必填<PartialTodo>;

// Pick: 选取指定属性
type TodoPreview = Pick<Todo, "title" | "completed">;

// Omit: 剔除指定属性
type TodoWithoutDesc = Omit<Todo, "description">;

// ReturnType: 提取函数返回值类型
function f() { return { x: 10, y: 3 }; }
type P = ReturnType<typeof f>;

// Parameters: 提取函数入参类型
type Params = Parameters<(a: number, b: string) => void>;

#keyof 与 typeof 关键字

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

type PersonKeys = keyof Person; // "name" | "age"

const person = { name: "Alice", age: 30 };
type PersonType = typeof person; // { name: string; age: number }

#infer 类型推导关键字

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

#条件控制与循环 (Conditionals and Loops)

#if 条件判断

const max: number = 100;
if (max > 50) {
  console.log("Large");
}

#三元运算符

const isEven: boolean = (10 % 2 === 0) ? true : false;

#switch 分支选择

const color: string = "red";
switch (color) {
  case "red":
    console.log("Stop");
    break;
  default:
    console.log("Go");
}

#For 循环

for (let i: number = 0; i < 5; i++) {
  console.log(i);
}

#While 循环

let count: number = 0;
while (count < 5) {
  console.log(count++);
}

#For...of 迭代器循环

const arr: number[] = [1, 2, 3];
for (const num of arr) {
  console.log(num);
}

#For...in 键名循环

const obj = { a: 1, b: 2 };
for (const key in obj) {
  console.log(key);
}

#数组与可迭代对象 (Arrays and Iterables)

#强类型数组高阶函数

const nums: number[] = [1, 2, 3];

// Map 映射
const doubled: number[] = nums.map(n => n * 2);

// Filter 过滤
const evens: number[] = nums.filter(n => n % 2 === 0);

// Reduce 归约
const sum: number = nums.reduce((acc, curr) => acc + curr, 0);

#只读数组 (Readonly Arrays)

const readOnlyNums: ReadonlyArray<number> = [1, 2, 3];
// readOnlyNums.push(4); // 编译报错:ReadonlyArray 不允许修改

#Set 集合对象

const set: Set<number> = new Set([1, 2, 3]);
set.add(4);
set.delete(1);

#Map 字典对象

const map: Map<string, number> = new Map();
map.set("one", 1);
map.get("one"); // 1

#对象 (Objects)

#对象类型标注

const car: { type: string, mileage?: number } = {
  type: "Toyota"
};

#可索引接口类型

interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = ["Bob", "Fred"];

#多余属性检查 (Excess Property Checks)

interface Square {
  color: string;
  width: number;
}

// const redSquare = { color: "red", width: 100, height: 100 }; // 严格模式下传递多余属性将报错

#模块与命名空间 (Modules and Namespaces)

#命名空间与内部模块

namespace Geometry {
  export interface Point {
    x: number;
    y: number;
  }
  export function distance(p1: Point, p2: Point): number {
    return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
  }
}

#模块解析配置 (Module Resolution)

// tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node"
  }
}

#异常处理 (Error Handling)

#Try Catch 捕获

try {
  throw new Error("Oops");
} catch (e: unknown) {
  if (e instanceof Error) {
    console.log(e.message);
  }
}

#自定义异常类

class CustomError extends Error {
  constructor(message: string) {
    super(message);
  }
}

#结合 ES 特性 (TypeScript with JavaScript Features)

#解构赋值类型标注

const [first, second]: [number, number] = [1, 2];
const { name: userName, age }: { name: string, age: number } = { name: "Alice", age: 30 };

#展开运算符

const arr1: number[] = [1, 2];
const arr2: number[] = [...arr1, 3, 4];

#模板字符串

const greeting: string = `Hello, ${name}`;

#箭头函数类型标注

const square = (x: number): number => x * x;