typescript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript

TypeScript

Type-safe JavaScript with static typing and modern features.
具备静态类型与现代特性的类型安全JavaScript。

Quick Start

快速开始

bash
bun init --typescript    # Initialize project
bunx tsc --noEmit        # Type check
vitest run               # Run tests
bash
bun init --typescript    # Initialize project
bunx tsc --noEmit        # Type check
vitest run               # Run tests

Configuration

配置

tsconfig.json

tsconfig.json

json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "lib": ["ESNext"],
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "baseUrl": ".",
    "paths": { "@/*": ["src/*"] }
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}
json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "lib": ["ESNext"],
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "baseUrl": ".",
    "paths": { "@/*": ["src/*"] }
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

Strict Mode Options

严格模式选项

OptionDescription
strictNullChecks
Enforce strict null checks
strictFunctionTypes
Strict function parameter types
noImplicitAny
Disallow implicit any types
alwaysStrict
Apply all strict checks
选项描述
strictNullChecks
启用严格的空值检查
strictFunctionTypes
启用严格的函数参数类型检查
noImplicitAny
禁止隐式any类型
alwaysStrict
启用所有严格检查

Type Definitions

类型定义

Basic Types

基础类型

typescript
let str: string = "hello";
let num: number = 42;
let bool: boolean = true;
let arr: number[] = [1, 2, 3];
let tuple: [string, number] = ["age", 25];
let obj: { name: string; age: number } = { name: "John", age: 30 };
typescript
let str: string = "hello";
let num: number = 42;
let bool: boolean = true;
let arr: number[] = [1, 2, 3];
let tuple: [string, number] = ["age", 25];
let obj: { name: string; age: number } = { name: "John", age: 30 };

Interfaces vs Types

接口 vs 类型别名

typescript
// Interface for object shapes
interface User {
  id: number;
  name: string;
  email: string;
}

// Type for unions and function signatures
type Status = "loading" | "success" | "error";
type CreateUser = (data: Partial<User>) => Promise<User>;

// Discriminated union
type Result<T> = { ok: true; value: T } | { ok: false; error: Error };
typescript
// Interface for object shapes
interface User {
  id: number;
  name: string;
  email: string;
}

// Type for unions and function signatures
type Status = "loading" | "success" | "error";
type CreateUser = (data: Partial<User>) => Promise<User>;

// Discriminated union
type Result<T> = { ok: true; value: T } | { ok: false; error: Error };

Utility Types

工具类型

typescript
type PartialUser = Partial<User>;
type RequiredUser = Required<User>;
type ReadonlyUser = Readonly<User>;
type UserName = Pick<User, "name">;
type UserWithoutEmail = Omit<User, "email">;
typescript
type PartialUser = Partial<User>;
type RequiredUser = Required<User>;
type ReadonlyUser = Readonly<User>;
type UserName = Pick<User, "name">;
type UserWithoutEmail = Omit<User, "email">;

Functions

函数

typescript
// Basic function
function add(a: number, b: number): number {
  return a + b;
}

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

// Optional parameters
function greet(name: string, title?: string): string {
  return title ? `${title} ${name}` : name;
}

// Rest parameters
function sum(...nums: number[]): number {
  return nums.reduce((a, b) => a + b, 0);
}

// Function overloads
function format(input: string): string;
function format(input: number): string;
function format(input: string | number): string {
  return String(input);
}

// Async function
async function fetchData(url: string): Promise<unknown> {
  const response = await fetch(url);
  return response.json();
}
typescript
// Basic function
function add(a: number, b: number): number {
  return a + b;
}

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

// Optional parameters
function greet(name: string, title?: string): string {
  return title ? `${title} ${name}` : name;
}

// Rest parameters
function sum(...nums: number[]): number {
  return nums.reduce((a, b) => a + b, 0);
}

// Function overloads
function format(input: string): string;
function format(input: number): string;
function format(input: string | number): string {
  return String(input);
}

// Async function
async function fetchData(url: string): Promise<unknown> {
  const response = await fetch(url);
  return response.json();
}

Classes

typescript
class Person {
  constructor(
    public name: string,
    private age: number,
  ) {}

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

// Inheritance
class Employee extends Person {
  constructor(
    name: string,
    age: number,
    public role: string,
  ) {
    super(name, age);
  }
}

// Abstract class
abstract class Shape {
  abstract area(): number;
}
typescript
class Person {
  constructor(
    public name: string,
    private age: number,
  ) {}

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

// Inheritance
class Employee extends Person {
  constructor(
    name: string,
    age: number,
    public role: string,
  ) {
    super(name, age);
  }
}

// Abstract class
abstract class Shape {
  abstract area(): number;
}

Generics

泛型

typescript
// Generic function
function wrap<T>(value: T): { value: T } {
  return { value };
}

// Generic class
class Container<T> {
  constructor(private value: T) {}
  get(): T {
    return this.value;
  }
}

// Generic constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
typescript
// Generic function
function wrap<T>(value: T): { value: T } {
  return { value };
}

// Generic class
class Container<T> {
  constructor(private value: T) {}
  get(): T {
    return this.value;
  }
}

// Generic constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

Type Guards

类型守卫

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

function isUser(value: unknown): value is User {
  return (
    typeof value === "object" &&
    value !== null &&
    "id" in value &&
    "name" in value
  );
}

function process(value: unknown) {
  if (isString(value)) {
    console.log(value.toUpperCase()); // value is string
  }
}
typescript
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function isUser(value: unknown): value is User {
  return (
    typeof value === "object" &&
    value !== null &&
    "id" in value &&
    "name" in value
  );
}

function process(value: unknown) {
  if (isString(value)) {
    console.log(value.toUpperCase()); // value is string
  }
}

Error Handling

错误处理

Custom Errors

自定义错误

typescript
class ValidationError extends Error {
  constructor(
    public field: string,
    message: string,
  ) {
    super(message);
    this.name = "ValidationError";
  }
}
typescript
class ValidationError extends Error {
  constructor(
    public field: string,
    message: string,
  ) {
    super(message);
    this.name = "ValidationError";
  }
}

Result Type

结果类型

typescript
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };

function safeParse(json: string): Result<unknown> {
  try {
    return { ok: true, value: JSON.parse(json) };
  } catch (error) {
    return { ok: false, error: error as Error };
  }
}
typescript
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };

function safeParse(json: string): Result<unknown> {
  try {
    return { ok: true, value: JSON.parse(json) };
  } catch (error) {
    return { ok: false, error: error as Error };
  }
}

Compilation

编译

bash
tsc                    # Compile
tsc --noEmit           # Type check only
tsc --watch            # Watch mode (use tmux)

tmux new -d -s tsc 'tsc --watch'
bash
tsc                    # Compile
tsc --noEmit           # Type check only
tsc --watch            # Watch mode (use tmux)

tmux new -d -s tsc 'tsc --watch'

Best Practices

最佳实践

  • Use
    strict: true
    in tsconfig
  • Avoid
    any
    - use
    unknown
    or specific types
  • Prefer interfaces for object shapes
  • Use branded types for primitives needing validation
  • Make invalid states unrepresentable
  • Type at boundaries (API inputs/outputs)
  • 在tsconfig中启用
    strict: true
  • 避免使用
    any
    类型,改用
    unknown
    或具体类型
  • 优先使用接口定义对象结构
  • 对需要验证的原始类型使用品牌类型
  • 让无效状态无法被表示
  • 在边界处添加类型校验(API输入/输出)

Tips

小贴士

  • tsc --noEmit
    for fast type checking
  • Gradual adoption with
    allowJs: true
  • Path mapping:
    "@/*": ["src/*"]
  • Declaration files:
    "declaration": true
  • Use
    // @ts-expect-error
    with error messages
  • 使用
    tsc --noEmit
    快速进行类型检查
  • 通过
    allowJs: true
    逐步迁移至TypeScript
  • 路径映射:
    "@/*": ["src/*"]
  • 声明文件:
    "declaration": true
  • 结合错误信息使用
    // @ts-expect-error