# 基础类型：构建数据的基石

## 概述

上一篇我们搭建了 TypeScript 环境，写下了 `name: string` 这样的类型注解。

`string` 就是一个**基础类型**。基础类型就像搭积木的最小单元——它们是构建复杂类型的基本材料。

TypeScript 的基础类型与 JavaScript 的原始类型一一对应：

| TypeScript 类型 | JavaScript 原始类型 | 示例 |
|----------------|-------------------|------|
| `string` | String | `"你好"`, `'hello'` |
| `number` | Number | `42`, `3.14`, `NaN` |
| `boolean` | Boolean | `true`, `false` |
| `bigint` | BigInt | `100n` |
| `symbol` | Symbol | `Symbol("id")` |
| `null` | Null | `null` |
| `undefined` | Undefined | `undefined` |

## string / number / boolean

这是最常见的三个类型：

```typescript
const name: string = "TypeScript"
const version: number = 5.6
const isAwesome: boolean = true
```

`number` 包含整数、浮点数、`NaN`、`Infinity`，JavaScript 的所有数值都是 `number` 类型：

```typescript
const integer: number = 42
const float: number = 3.14
const notANumber: number = NaN
const infinity: number = Infinity
```

## bigint 与 symbol

**bigint** 表示任意精度的整数，适合处理超大数值：

```typescript
const big: bigint = 100n
const another = BigInt("9007199254740991")
```

**symbol** 表示唯一标识符，常用于对象属性的键：

```typescript
const key: symbol = Symbol("id")
const key2 = Symbol("id")
// key !== key2，两个 symbol 永远不同
```

## null 与 undefined

`null` 和 `undefined` 在 TypeScript 中有各自的类型：

```typescript
const empty: null = null
const notDefined: undefined = undefined
```

在开启 `strict: true` 的情况下，它们只能赋值给自己，不能赋值给其他类型：

```typescript
const name: string = null      // ❌ 严格模式下报错
const age: number = undefined  // ❌ 严格模式下报错
```

> [!info] 说明
> 非严格模式下，`null` 和 `undefined` 可以赋值给任何类型。但项目应始终开启 `strict: true`——这是 TypeScript 最大的价值所在。

## 类型推断

你不需要每次都写明类型。TypeScript 会根据值自动推断：

```typescript
const name = "TypeScript"   // 推断为 string
const age = 5               // 推断为 number
const isAwesome = true       // 推断为 boolean
```

用 `const` 声明的字面量，TypeScript 会推断为最精确的类型：

```typescript
const greeting = "你好"      // 类型为 "你好"（字面量类型）
let message = "你好"         // 类型为 string
```

## 字面量类型

当变量的值被限定为某一个具体值时，值本身就可以作为类型：

```typescript
const direction: "left" = "left"
// direction 只能取 "left"

let color: "red" | "green" | "blue" = "red"
// color 只能取 red、green、blue 中的一个
```

## any 与 unknown

**any** 是类型系统的"逃生舱"。声明为 `any` 的变量，TypeScript 会关闭它的类型检查：

```typescript
let value: any = "hello"
value = 42           // ✅ 不报错
value.toUpperCase()  // ✅ 不报错（但运行时可能崩溃）
```

`any` 让你回到了 JavaScript 的世界——自由，但危险。

**unknown** 是类型安全的 `any`。它表示"我不知道这是什么类型"，但使用前必须验证：

```typescript
let value: unknown = "hello"

value.toUpperCase()  // ❌ 不能直接调用，类型未知

// 必须先验证
if (typeof value === "string") {
  value.toUpperCase()  // ✅ 验证后可以使用
}
```

| 对比 | any | unknown |
|------|-----|---------|
| 赋值给别人 | 可以赋值给任何类型 | 只能赋值给 any 和 unknown |
| 调用方法 | 可以调用任何方法 | 必须先进行类型检查 |
| 安全性 | 无 | 有 |

> [!tip] 技巧
> 当你不确定一个值的类型时，优先用 `unknown`，而不是 `any`。它强迫你在使用前做类型验证，避免运行时错误。

---

基础类型是类型系统的起点。你现在能描述一个值"是什么"了。

除了这些，还有 `void`（函数无返回值）和 `never`（永不发生）两个特殊类型，它们更多出现在函数和类型守卫的上下文中，后面用到时再细说。

但现实世界的数据很少是孤立的——**一个值往往属于一个集合：数组、元组、对象……** 下一组类型就是处理这些"复合"情况的。


---

> 作者: Aphros  
> URL: https://blog.papergate.top/posts/02.%E5%9F%BA%E7%A1%80%E7%B1%BB%E5%9E%8B%E6%9E%84%E5%BB%BA%E6%95%B0%E6%8D%AE%E7%9A%84%E5%9F%BA%E7%9F%B3/  

