强曰为道

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

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()); // ✅
特性anyunknown
可以赋值给其他类型
可以调用方法❌(需先检查)
类型安全
使用场景临时兼容安全的动态类型

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) => {}; // ✅

扩展阅读