强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

TypeScript 开发指南 / 03 - 基本类型

基本类型

类型系统概览

TypeScript 的类型系统分为两大类:

类别 包含类型 说明
原始类型(Primitive) string, number, boolean, null, undefined, symbol, bigint 不可变的基础值
引用类型(Reference) object, array, tuple, enum, function, class 可变的复合结构
特殊类型 any, unknown, never, void 用于特定场景
高级类型 联合、交叉、字面量、泛型等 后续章节详述

原始类型(Primitive Types)

string(字符串)

// 字符串类型注解
const name: string = "Alice";
const greeting: string = `Hello, ${name}!`; // 模板字符串也支持

// 多行字符串
const html: string = `
  <div>
    <h1>${name}</h1>
  </div>
`;

number(数字)

TypeScript 的 number 类型包含整数和浮点数,也支持特殊数值:

const age: number = 25;
const price: number = 99.99;
const hex: number = 0xff;        // 十六进制
const binary: number = 0b1010;   // 二进制
const octal: number = 0o744;     // 八进制
const million: number = 1_000_000; // 数字分隔符(ES2021)

// 特殊值
const notANumber: number = NaN;
const infinity: number = Infinity;

注意:TypeScript 没有专门的 integer 类型,所有数字都是 IEEE 754 双精度浮点数。

boolean(布尔值)

const isActive: boolean = true;
const isDeleted: boolean = false;

// 逻辑运算
const result: boolean = isActive && !isDeleted;

null 和 undefined

const nothing: null = null;
const notDefined: undefined = undefined;

// 在 strictNullChecks 模式下,null 和 undefined 是独立类型
// 不能赋值给其他类型
const name: string = null; // ❌ 错误(strictNullChecks: true)
const name: string | null = null; // ✅ 正确
typeof 说明
null "object" 表示"无值"
undefined "undefined" 表示"未定义"

symbol(符号)

const id: symbol = Symbol("id");
const anotherId: symbol = Symbol("id");

// 每个 Symbol 都是唯一的
console.log(id === anotherId); // false

// 用作对象属性键
const user = {
  [id]: 12345,
  name: "Alice"
};

console.log(user[id]); // 12345

bigint(大整数)

// ES2020 引入,用于表示任意精度整数
const largeNumber: bigint = 9007199254740991n;
const anotherBig: bigint = BigInt(9007199254740991);

// 不能与 number 混合运算
const sum = largeNumber + 10; // ❌ 错误
const sum = largeNumber + 10n; // ✅ 正确

类型注解(Type Annotation)

类型注解使用冒号 : 语法显式声明变量的类型:

// 变量声明
const name: string = "Alice";
let age: number = 25;
const isActive: boolean = true;

// 数组声明
const numbers: number[] = [1, 2, 3];
const names: Array<string> = ["Alice", "Bob"]; // 泛型语法

// 对象声明
const user: { name: string; age: number } = {
  name: "Alice",
  age: 25
};

注解的位置

// 变量注解
let count: number = 0;

// 函数参数注解
function greet(name: string): string {
  return `Hello, ${name}!`;
}

// 函数返回值注解
function add(a: number, b: number): number {
  return a + b;
}

// 类型注解是可选的——TypeScript 可以推断类型
let count = 0; // TypeScript 推断为 number 类型

类型推断(Type Inference)

TypeScript 的类型推断引擎非常强大,在大多数情况下不需要显式注解:

// TypeScript 自动推断类型
let name = "Alice";        // 推断为 string
let age = 25;              // 推断为 number
let isActive = true;       // 推断为 boolean
let items = [1, 2, 3];     // 推断为 number[]
let user = {               // 推断为 { name: string; age: number }
  name: "Alice",
  age: 25
};

// 函数返回值也会被推断
function add(a: number, b: number) {
  return a + b; // 推断返回值为 number
}

何时需要显式注解?

场景 是否需要注解 示例
变量有初始值 通常不需要 let x = 10
函数参数 必须注解 function f(x: number)
函数返回值 建议注解 function f(): number
空数组 需要注解 let arr: number[] = []
null 初始值 需要注解 let el: HTMLElement | null = null
复杂对象 建议注解或使用接口 见第 5 章
// 空数组需要注解
let items = [];           // 推断为 any[](不推荐)
let items: number[] = []; // ✅ 明确类型

// null 初始值需要注解
let element = null;                    // 推断为 any
let element: HTMLElement | null = null; // ✅ 明确类型

// 函数参数必须注解
function multiply(a, b) {     // ❌ 隐式 any(noImplicitAny: true 时报错)
  return a * b;
}
function multiply(a: number, b: number) { // ✅
  return a * b;
}

特殊类型

any(任意类型)

any 类型会绕过类型检查,应尽量避免使用:

// any 允许任何操作
let value: any = "hello";
value = 42;        // ✅
value.foo();       // ✅(编译不报错,但运行时可能出错)
value = true;      // ✅

// 什么时候可以使用 any?
// 1. 迁移旧代码时临时使用
// 2. 第三方库没有类型定义时
// 3. 处理动态数据(如 JSON.parse)
const data: any = JSON.parse('{"name": "Alice"}');

注意:在 strict 模式下,应尽量用 unknown 替代 any

unknown(未知类型)

unknown 是类型安全的 any,使用前必须进行类型检查:

let value: unknown = "hello";

// 不能直接使用
value.toUpperCase(); // ❌ 错误:类型 "unknown" 上不存在属性 "toUpperCase"

// 必须先进行类型检查
if (typeof value === "string") {
  console.log(value.toUpperCase()); // ✅ 类型收窄为 string
}

// 或使用类型断言
console.log((value as string).toUpperCase()); // ✅
特性 any unknown
可以赋值给其他类型
可以调用方法 ❌(需先检查)
类型安全
使用场景 临时兼容 安全的动态类型

void

void 表示函数没有返回值:

function logMessage(message: string): void {
  console.log(message);
  // 没有 return 语句,或 return;
}

// void 变量(通常不常用)
let unusable: void = undefined;

never

never 表示永远不会发生的类型:

// 抛出异常的函数
function throwError(message: string): never {
  throw new Error(message);
}

// 无限循环
function infiniteLoop(): never {
  while (true) {}
}

// 穷尽检查
type Shape = "circle" | "square" | "triangle";

function getArea(shape: Shape): number {
  switch (shape) {
    case "circle":
      return Math.PI * 10 ** 2;
    case "square":
      return 10 * 10;
    case "triangle":
      return 0.5 * 10 * 10;
    default:
      const _exhaustive: never = shape; // 如果遗漏了某个 case,这里会报错
      return _exhaustive;
  }
}

object

object 类型表示非原始类型的值:

// object 类型
const person: object = { name: "Alice" };
const arr: object = [1, 2, 3];

// 更推荐使用具体的对象类型
const person: { name: string; age: number } = {
  name: "Alice",
  age: 25
};

类型断言(Type Assertion)

当你比 TypeScript 更了解某个值的类型时,可以使用类型断言:

// as 语法(推荐)
const input = document.getElementById("myInput") as HTMLInputElement;
input.value = "Hello";

// 尖括号语法(JSX 中不能使用)
const input = <HTMLInputElement>document.getElementById("myInput");

// 双重断言(极端情况,不推荐)
const value = "hello" as any as number; // 编译通过,但逻辑上错误

注意:类型断言不进行运行时转换,它只是告诉编译器"相信我,我知道这个值的类型"。

常见的内置对象类型

TypeScript 内置了许多常用的对象类型:

// 日期
const now: Date = new Date();

// 正则表达式
const pattern: RegExp = /hello/gi;

// 错误
const error: Error = new Error("Something went wrong");

// Promise
const promise: Promise<string> = new Promise((resolve) => {
  resolve("done");
});

// Map 和 Set
const map: Map<string, number> = new Map();
map.set("age", 25);

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

业务场景:表单数据类型定义

// 定义表单数据接口
interface LoginForm {
  username: string;
  password: string;
  rememberMe: boolean;
}

interface RegistrationForm extends LoginForm {
  email: string;
  age: number;
  agreeToTerms: boolean;
}

// 表单验证函数
function validateLogin(form: LoginForm): string[] {
  const errors: string[] = [];

  if (form.username.length < 3) {
    errors.push("用户名至少 3 个字符");
  }
  if (form.password.length < 8) {
    errors.push("密码至少 8 个字符");
  }

  return errors;
}

// 使用
const form: LoginForm = {
  username: "alice",
  password: "12345678",
  rememberMe: true
};

const errors = validateLogin(form);
if (errors.length === 0) {
  console.log("验证通过");
} else {
  console.log("验证失败:", errors);
}

类型兼容性速查

// 原始类型:值相等即可
let a: string = "hello";
let b: string = a; // ✅

// 对象类型:结构兼容(鸭子类型)
interface Point {
  x: number;
  y: number;
}

const point3D = { x: 1, y: 2, z: 3 };
const point2D: Point = point3D; // ✅ 多余属性兼容

// 函数类型:参数和返回值兼容
type Handler = (a: number) => void;
const handler: Handler = (a: number, b?: number) => {}; // ✅

扩展阅读