1-4 TypeScript 中的 `number`、`bigint` 与 `string`

TypeScript 中的 numberbigintstring

摘要

numberbigintstring 都是 TypeScript 的原始类型。本篇重点整理它们的声明、推断、字面量类型、运算规则及常见误区。

背景

TypeScript 在 JavaScript 原始值的基础上增加了静态类型检查。理解这三个类型时,需要同时区分:

  • 基础类型 :表示一类值,如 numberbigintstring
  • 字面量类型 :只表示一个确定的值,如 100100n'success'
  • 运行时值:类型检查最终仍遵循 JavaScript 的数值、字符串和运算规则。

类型对比

类型 可表示的值 字面量示例 typeof 结果
number 整数、浮点数、NaNInfinity 1003.14 'number'
bigint 任意精度的整数 100n 'bigint'
string 文本字符串 'hello'"hello"hello 'string'

注意事项 :类型标注应使用小写的 numberbigintstring,不要使用包装对象类型 NumberBigIntString

number

核心概念

  • 定义number 表示 JavaScript 中的普通数值,不单独区分整数和浮点数。
  • 存储方式:普通数值采用 IEEE 754 双精度浮点数表示。
  • 安全整数范围 :能够被精确表示的整数范围是 -(2^53 - 1)2^53 - 1,边界可通过 Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER 获取。
  • 特殊值NaNInfinity-Infinity 也属于 number
  • 官方文档The primitives: string, number, and boolean

声明与类型推断

ts 复制代码
let count = 100;
let price: number = 19.9;
const statusCode = 200;
let fixedCode: 200 = 200;

console.log(typeof count); // 输出: number
  • count 使用 let 声明,通常会拓宽为 number
  • price 显式标注为 number,可以接收不同的普通数值。
  • statusCode 使用 const 声明,类型会被推断为字面量类型 200
  • fixedCode 被显式限制为字面量类型 200,不能赋值为其他数字。

不同进制的数字字面量

ts 复制代码
const decimal = 20;
const binary = 0b10100;
const octal = 0o24;
const hexadecimal = 0x14;

console.log(decimal === binary && binary === octal && octal === hexadecimal); // 输出: true

这些写法只影响代码中的表示形式,运行时得到的值都属于 number

精度问题

ts 复制代码
const unsafeInteger = Number.MAX_SAFE_INTEGER + 1;

console.log(unsafeInteger === Number.MAX_SAFE_INTEGER + 2); // 输出: true
console.log(0.1 + 0.2 === 0.3); // 输出: false
  • 超出安全整数范围后,相邻整数可能无法准确区分。
  • 浮点数采用二进制表示,某些十进制小数无法被精确存储。
  • 金额计算不能直接假定浮点运算绝对精确,常见做法是转换为最小货币单位后使用整数计算。

注意事项

  • 判断一个值是否为 NaN 时,优先使用 Number.isNaN(),因为 NaN !== NaN
  • 需要判断整数是否仍在安全范围内时,可以使用 Number.isSafeInteger()
  • 如果需要处理超过安全整数范围的整数,应考虑使用 bigint,而不是继续使用 number

bigint

核心概念

  • 定义bigint 是 ES2020 提供的任意精度整数类型,适合表示超出 number 安全整数范围的整数。
  • 限制:只能表示整数,不能表示小数。
  • 类型关系bigintnumber 是两个独立的类型,不能直接互相赋值或混合进行算术运算。
  • 官方文档TypeScript 3.2 - BigInt

创建方式

ts 复制代码
const largeId = 9007199254740993n;
const orderId = BigInt('9007199254740993');
let total: bigint = 100n;
const fixedTotal: 100n = 100n;

console.log(typeof largeId); // 输出: bigint
  • 在整数字面量后添加 n 可以创建 bigint,如 100n
  • BigInt() 可以把合法的整数或整数字符串转换为 bigint
  • 对超出安全整数范围的值,优先传入字符串,避免它在进入 BigInt() 前已经丢失精度。
ts 复制代码
const precise = BigInt('9007199254740993');
const alreadyRounded = BigInt(9007199254740993);

console.log(precise); // 输出: 9007199254740993n
console.log(alreadyRounded); // 输出: 9007199254740992n

运算规则

ts 复制代码
const left = 10n;
const right = 3n;

console.log(left + right); // 输出: 13n
console.log(left / right); // 输出: 3n
console.log(10n < 20); // 输出: true
  • bigint 之间可以进行加、减、乘、除、取余和幂运算。
  • 除法结果会直接截去小数部分,例如 10n / 3n 的结果是 3n
  • numberbigint 可以进行部分关系比较,但不能直接混合进行算术运算。

下面两种写法都会产生类型错误:

ts 复制代码
let normalValue: number = 100;
let bigValue: bigint = 100n;

normalValue = bigValue;
const result = normalValue + bigValue;

需要先根据业务语义显式转换类型:

ts 复制代码
const numberResult = 10 + Number(20n);
const bigintResult = BigInt(10) + 20n;

console.log(numberResult); // 输出: 30
console.log(bigintResult); // 输出: 30n

编译与运行环境

使用 100n 这类 bigint 字面量时,tsconfig.json 中的 target 应设置为 ES2020 或更高版本;使用 BigInt() 还需要相应的标准库和运行时支持。

json 复制代码
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM"]
  }
}

注意事项

  • 123.45n 是非法写法,因为 bigint 字面量必须是整数。
  • 将很大的 bigint 转换为 number 可能丢失精度。
  • BigInt(1.5) 会在运行时抛出错误,因为传入的数值不是整数。
  • 原生 JSON.stringify() 不能直接序列化 bigint,需要先转换为字符串或提供自定义序列化逻辑。

string

核心概念

  • 定义string 表示 JavaScript 中的字符串原始值。
  • 写法:可以使用单引号、双引号或模板字符串创建字符串。
  • 不可变性:字符串本身不可变,字符串方法会返回新字符串,而不是修改原字符串。
  • 官方文档The primitives: string, number, and boolean

声明与字符串形式

ts 复制代码
const singleQuoted = 'TypeScript';
const anotherText = 'JavaScript';
const version = 5;
const templateText = `TypeScript ${version}`;
let message: string = 'hello';

console.log(templateText); // 输出: TypeScript 5
console.log(typeof message); // 输出: string
  • 单引号和双引号创建的字符串没有类型差异。
  • 模板字符串使用反引号,可以插入表达式,也可以直接书写多行文本。

字符串字面量类型

字符串字面量类型可以把变量限制在明确的字符串集合内:

ts 复制代码
type RequestMethod = 'GET' | 'POST';

let method: RequestMethod = 'GET';
method = 'POST';

console.log(method); // 输出: POST

这种写法比宽泛的 string 更精确,适合表示状态、操作类型、配置项等有限值。

模板字面量类型

模板字面量不仅能创建字符串值,也能在类型层面组合字符串格式。

ts 复制代码
type EventName = 'click' | 'change';
type HandlerName = `on${Capitalize<EventName>}`;

const handler: HandlerName = 'onClick';

console.log(handler); // 输出: onClick

注意事项

  • 日常类型标注应使用 string,不要使用包装对象类型 String
  • const name = 'Tom' 通常推断为字面量类型 'Tom'let name = 'Tom' 通常会拓宽为 string
  • String(value) 可将值转换为字符串;模板字符串中的插值也会触发字符串转换。

类型推断与字面量类型总结

ts 复制代码
let mutableNumber = 10;
const immutableNumber = 10;
let mutableBigInt = 10n;
const immutableBigInt = 10n;
let mutableString = 'hello';
const immutableString = 'hello';

以上变量通常会被推断为:

声明 推断类型
let mutableNumber = 10 number
const immutableNumber = 10 10
let mutableBigInt = 10n bigint
const immutableBigInt = 10n 10n
let mutableString = 'hello' string
const immutableString = 'hello' 'hello'

工作机制let 声明的变量可能在后续被重新赋值,因此 TypeScript 通常会将字面量拓宽为对应的基础类型;const 变量不能重新赋值,因此可以保留更精确的字面量类型。

类型转换总结

目标类型 常用转换方式 主要风险
number Number(value) 无效字符串得到 NaN;大整数可能丢失精度
bigint BigInt(value) 小数或非法字符串会抛出错误
string String(value) 对象转换结果取决于自身的字符串转换逻辑

常见误区

  • 误区number 只表示小数,整数应该使用其他类型。

    正确理解 :JavaScript 和 TypeScript 的 number 同时表示普通整数与浮点数。

  • 误区bigint 是范围更大的 number,二者可以直接混合计算。

    正确理解:二者是独立的原始类型,算术运算前必须显式统一类型。

  • 误区bigint 适合所有高精度计算。

    正确理解bigint 只能精确表示整数,不能直接解决小数精度问题。

  • 误区Stringstring 可以在类型标注中随意替换。

    正确理解string 是字符串原始类型,String 是包装对象类型,日常开发应使用小写形式。

  • 误区 :类型标注能够改变 JavaScript 的运行时行为。

    正确理解:TypeScript 类型主要在编译阶段提供检查,最终的数值精度、类型转换和运算行为仍由 JavaScript 决定。

相关推荐
小赵同学WoW1 小时前
1-3 `boolean` 与字面量类型
前端
光影少年1 小时前
react navite 长列表优化:FlatList / SectionList 原理与优化属性
前端·react native·react.js
cindershade1 小时前
鼠标 3D 倾斜卡片
前端
wordbaby1 小时前
从双端内卷到一库多端:基于 pnpm + Taro 4 + RNOH 鸿蒙的 Monorepo 跨端架构实战
前端·微信小程序·app
子兮曰1 小时前
DeepSeek Harness 架构深潜:一个把 Agent 运行时做成纯插件树的开源 Harness
前端·后端·deepseek
子兮曰2 小时前
AI Agent 完整入门指南:从 LLM 到生产落地的 30+ 个核心概念
前端·后端·agent
楚宝ovo2 小时前
新增一个 demo 子应用 - 微前端
前端
JarvanMo3 小时前
Dart 3.13:小版本,大动作
前端
纯粹的热爱3 小时前
Ubuntu 安装 Node.js 22.x(通过 NodeSource 官方源)
前端