Skip to main content

TypeScript 基础类型速查

· 4 min read

TS 基础类型 10 年没变,但 几个反直觉的细节 容易踩坑。

  • 原始类型:boolean / number / string / bigint / symbol / null / undefined
  • unknown > any必须先 narrow 才能用,比 any 安全
  • 三个长得像object / Object / {} 是三种不同类型
  • void 不只是 "无返回":也指代 undefined 这个值
  • Tuple 陷阱:长度不可越界,但 push() 能扩

原始类型(一句话)

类型说明例子
boolean真假值truefalse
number整数和浮点1233.14
string字符串'abc'
bigint大整数123n
symbol唯一值Symbol('foo')
null空值null
undefined未定义undefined
warning

bigintnumber 不能混算——1n + 1 会报错,要么 1n + 1n 要么 Number(1n) + 1

strictNullChecks 2026 年默认开启,null / undefined 不再是其他类型的子类型。number | null | undefined 是显式标注,不是默认行为。


any vs unknown:现代推荐 unknown

any 完全绕过类型检查,unknown 必须先 narrow 才能用:

let a: any = 123;
a.toUpperCase(); // 编译通过,运行炸

let u: unknown = 123;
u.toUpperCase(); // 编译报错:Object is of type 'unknown'
Best Practice

能用 unknown 就别用 anyunknown 是"我不知道类型,但用之前必须先查清楚"的承诺。

unknown 的常见 narrow 方式:

function handle(value: unknown) {
if (typeof value === 'string') {
value.toUpperCase(); // OK,已 narrow 为 string
}
if (value instanceof Date) {
value.getTime(); // OK,已 narrow 为 Date
}
}
info

第三方库返回的 any、JSON 解析结果、用户输入——这些场景一律先标 unknown,再 narrow。


object vs Object vs

三个长得像但含义完全不同

写法含义用途
object所有非原始类型(数组、对象、函数)新代码默认
Object所有 JS 对象的公共方法(toStringhasOwnProperty几乎不用
{}空对象,但能访问 Object 上的方法几乎不用
warning

新代码只用 object 即可——Object{} 都是历史包袱,会让 prettySure.toFixed() 这种属性访问报错(属性不在原型链上)。

let obj: object = { x: 1 };
obj.x; // Error:Property 'x' does not exist on type 'object'
obj['x']; // 同上

要访问具体属性,老老实实写对象字面量类型

let obj: { x: number } = { x: 1 };
obj.x = 2; // OK

void:不是"无"而是 undefined

void 在 TS 里有两个含义:

  1. 函数返回值:函数不返回任何值
  2. 类型本身:只有 undefined(关闭 strictNullChecks 时也接受 null)能赋值
function sayHi(): void {
console.log('Hi');
}

let v: void = undefined; // OK
let v2: void = sayHi(); // OK(sayHi 隐式返回 undefined)
info

void 不是"什么都没有"——它是 undefined 的类型别名。never 才是真正的"什么都没有"。

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

function loop(): never {
while (true) { /* ... */ }
}

never 用于"函数永远不返回"——要么抛错要么死循环。


Tuple 陷阱:长度不可越界,但 push() 能扩

let t: [number, string] = [1, 'a'];
t[2]; // Error:length 2 has no element at index 2

t.push(2); // 编译通过!运行时 t = [1, 'a', 2]
t[2]; // 还是 Error(TS 不知道你 push 了)
Best Practice

tuple 只在长度完全确定时用。否则用 [number, string] + 显式 length 检查,或者干脆 Array<number | string>

带命名字段的 tuple 更易读:

type Point = [x: number, y: number];
type UserEntry = [id: string, name: string, createdAt: Date];

Array 两种写法

let a1: number[] = [1, 2, 3]; // 简写,常见
let a2: Array<number> = [1, 2, 3]; // 泛型写法
let a3: (number | string)[] = [1, 'a']; // 联合类型数组

写法 1 更简洁,写法 2 在复杂嵌套时更清晰(Array<Array<number>>number[][] 易读)。

只读数组用 readonly

const arr: readonly number[] = [1, 2, 3];
arr.push(4); // Error

Function 类型

参数和返回值分开标注:

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

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

函数类型本身可以提取:

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

References

  1. TypeScript Handbook: Everyday Types —— 官方手册
  2. TypeScript: Object vs object vs - stackoverflow —— 三个类型的对比
  3. The object Type in TypeScript - Marius Schulz —— object 类型详解
  4. TypeScript: any vs unknown —— unknown 推荐用法的讨论