ToolkitX
知识库工具箱

TypeScript 入门

安装、配置、基础类型注解

20min·入门

01. TypeScript 是什么、解决了什么问题

TypeScript 是 JavaScript 的超集——所有合法的 JS 代码都是合法的 TS 代码。它在 JS 之上加了类型系统,编译时(不是运行时)做类型检查。 TypeScript 解决的问题: 1. 类型错误提前发现——拼错属性名、传错参数类型,在写代码时 IDE 就报红,不用等到运行才发现。 2. 更好的 IDE 体验——自动补全、参数提示、重构工具,全都基于类型信息。 3. 自文档化——接口和类型定义就是最好的 API 文档。新同事看代码就知道这个函数要什么参数返回什么结果。 4. 大型项目的可维护性——几万行 JS 代码改了不敢部署?TS 让你改之前编译就知道哪些地方受影响。 TS 代码经过 tsc(TypeScript Compiler)编译成 JS 才能运行。类型信息在编译后全被擦除,不影响运行时性能。
bash
# 安装 TypeScript
npm install -g typescript

# 初始化项目
tsc --init  # 创建 tsconfig.json

# 编译
tsc               # 编译整个项目
tsc --watch       # 监视模式,文件一变就编译
tsc --noEmit      # 只检查类型,不输出 JS 文件

02. 基础类型注解

TypeScript 的类型注解写在一个冒号后面:变量: 类型。基本类型有 string、number、boolean、null、undefined、any、unknown。 类型推断——大部分情况下你不写类型注解 TS 也能根据初始值自动推断类型。let name = 'Alice' 自动推断为 string。只有初始值无法推断时(如函数参数)才必须写类型。 any——任何类型,相当于关闭类型检查。别滥用——用了 any 等于放弃 TS 的保护。unknown——安全的 any,在对 unknown 类型的值做任何操作前必须先类型检查。 数组写法:number[] 或 Array<number>。元组(Tuple):[string, number] 固定长度和类型的数组。
typescript
// 基础类型
let name: string = 'Alice';
let age: number = 36;
let isActive: boolean = true;

// 类型推断(不需要写类型注解)
let city = 'Beijing';  // TS 自动推断为 string

// any vs unknown
let data: any = 123;
data.toUpperCase();    // 不报错但运行时报错!

let info: unknown = 123;
// info.toUpperCase(); // 编译报错!必须先检查类型
if (typeof info === 'string') {
  info.toUpperCase();  // 安全了
}

// 数组和元组
let list: number[] = [1, 2, 3];
let tuple: [string, number] = ['Alice', 36];
unknown 是 any 的安全替代——对 unknown 类型的值做任何操作前都必须缩小类型范围。养成尽量不用 any 的习惯。

03. 函数类型

函数的类型包括参数类型和返回值类型。参数类型必须写(除非有默认值),返回值类型可省略(TS 能推断)。 可选参数:参数名后加 ?——表示这个参数可以不传。默认参数:参数名 = 默认值——跟 JS 一样但 TS 能自动推断类型。 剩余参数:...args: number[]——跟 JS 一样但是要加类型注解。 函数重载:同一个函数可以有不同的参数和返回值组合。用多个函数签名加一个实现签名。 void 返回类型——函数没有返回值(或返回 undefined)。never——函数永远不会执行完(抛异常或死循环)。
typescript
// 函数类型
function add(a: number, b: number): number {
  return a + b;
}

// 可选参数和默认值
function greet(name: string, greeting?: string): string {
  return `${greeting || 'Hello'}, ${name}`;
}

function multiply(a: number, b = 1): number {
  return a * b;  // b 自动推断为 number
}

// 函数重载
function process(x: string): string;
function process(x: number): number;
function process(x: string | number): string | number {
  if (typeof x === 'string') return x.toUpperCase();
  return x * 2;
}
函数参数的类型注解不能省略(除非有默认值可以推断)。如果参数没写类型,TS 会隐式标为 any——在 strict 模式下会报错。

04. tsconfig.json——TypeScript 的配置文件

tsconfig.json 是 TypeScript 项目的核心配置文件。几个最常用的选项: target——编译输出到哪个 JS 版本(ES5/ES6/ESNext)。现代项目一般 ESNext 或 ES2022。 module——使用什么模块系统(CommonJS/ESNext)。Node.js 项目用 CommonJS,前端打包的项目用 ESNext 让打包工具处理。 strict——严格模式的总开关,开启后会自动启用 noImplicitAny、strictNullChecks 等所有严格检查。强烈建议开启! outDir——编译输出目录(如 ./dist)。 rootDir——源代码目录(如 ./src)。 include/exclude——指定包含/排除哪些文件。 paths——路径别名。把 @/utils 映射到 src/utils,不用写 ../../utils。配合打包工具(Webpack/Vite)的别名一起用。
json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
strict: true 一开始可能报很多错,但这些都是潜在的 bug。习惯严格模式后写出来的代码质量高一大截。

05. 枚举与 literal 类型

枚举(enum)把一组相关常量集合在一起。TS 的 enum 编译成 JS 后会变成双向映射的对象(数字枚举)或字符串映射。 const enum——编译时内联,不生成 JS 对象。性能更好但不能运行时反向查找。 有些团队不喜欢 enum(因为编译后多出 JS 代码),用 union type 代替:type Color = 'red' | 'green' | 'blue'。这叫字面量类型加联合类型——字符串枚举值,编译后零开销。 选 enum 还是 union:需要反向查找(从值找键名)用 enum,只做类型约束用 union type。现代 TS 项目倾向用 union type。
typescript
// enum
enum Direction {
  North = 'N',
  South = 'S',
  East  = 'E',
  West  = 'W'
}
function move(dir: Direction) {}
move(Direction.North);

// const enum(编译后无额外 JS 代码)
const enum Size { Small, Medium, Large }
const s: Size = Size.Small;

// union type 替代 enum
// type Direction = 'North' | 'South' | 'East' | 'West';
// function move(dir: Direction) {}
// move('North');
const enum 编译后被内联替换为常量值,不留任何 enum 对象。但有些打包工具在 transpileOnly 模式下需要额外配置才能支持 const enum。

知识测验

1/5正确 0

TypeScript 的类型检查发生在什么阶段?

下一节

类型系统

下一节