TypeScript 中number、bigint与 string
作者:小赵同学WoW
摘要
number、bigint 和 string 都是 TypeScript 的原始类型。本篇重点整理它们的声明、推断、字面量类型、运算规则及常见误区。
背景
TypeScript 在 JavaScript 原始值的基础上增加了静态类型检查。理解这三个类型时,需要同时区分:
- 基础类型:表示一类值,如 number、bigint、string。
- 字面量类型:只表示一个确定的值,如 100、100n、'success'。
- 运行时值:类型检查最终仍遵循 JavaScript 的数值、字符串和运算规则。
类型对比
| 类型 | 可表示的值 | 字面量示例 | typeof 结果 |
|---|---|---|---|
| number | 整数、浮点数、NaN、Infinity 等 | 100、3.14 | 'number' |
| bigint | 任意精度的整数 | 100n | 'bigint' |
| string | 文本字符串 | 'hello'、"hello"、`hello` | 'string' |
注意事项:类型标注应使用小写的 number、bigint、string,不要使用包装对象类型 Number、BigInt、String。
number
核心概念
- 定义:number 表示 JavaScript 中的普通数值,不单独区分整数和浮点数。
- 存储方式:普通数值采用 IEEE 754 双精度浮点数表示。
- 安全整数范围:能够被精确表示的整数范围是 -(2^53 - 1) 到 2^53 - 1,边界可通过 Number.MIN_SAFE_INTEGER 和 Number.MAX_SAFE_INTEGER 获取。
- 特殊值:NaN、Infinity 和 -Infinity 也属于 number。
- 官方文档:The primitives: string, number, and boolean
声明与类型推断
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,不能赋值为其他数字。
不同进制的数字字面量
const decimal = 20; const binary = 0b10100; const octal = 0o24; const hexadecimal = 0x14; console.log(decimal === binary && binary === octal && octal === hexadecimal); // 输出: true
这些写法只影响代码中的表示形式,运行时得到的值都属于 number。
精度问题
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安全整数范围的整数。 - 限制:只能表示整数,不能表示小数。
- 类型关系:
bigint与number是两个独立的类型,不能直接互相赋值或混合进行算术运算。 - 官方文档:TypeScript 3.2 - BigInt
创建方式
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() 前已经丢失精度。
const precise = BigInt('9007199254740993');
const alreadyRounded = BigInt(9007199254740993);
console.log(precise); // 输出: 9007199254740993n
console.log(alreadyRounded); // 输出: 9007199254740992n
运算规则
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。
- number 与 bigint 可以进行部分关系比较,但不能直接混合进行算术运算。
下面两种写法都会产生类型错误:
let normalValue: number = 100; let bigValue: bigint = 100n; normalValue = bigValue; const result = normalValue + bigValue;
需要先根据业务语义显式转换类型:
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() 还需要相应的标准库和运行时支持。
{
"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
声明与字符串形式
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
- 单引号和双引号创建的字符串没有类型差异。
- 模板字符串使用反引号,可以插入表达式,也可以直接书写多行文本。
字符串字面量类型
字符串字面量类型可以把变量限制在明确的字符串集合内:
type RequestMethod = 'GET' | 'POST'; let method: RequestMethod = 'GET'; method = 'POST'; console.log(method); // 输出: POST
这种写法比宽泛的 string 更精确,适合表示状态、操作类型、配置项等有限值。
模板字面量类型
模板字面量不仅能创建字符串值,也能在类型层面组合字符串格式。
type EventName = 'click' | 'change';
type HandlerName = `on${Capitalize<EventName>}`;
const handler: HandlerName = 'onClick';
console.log(handler); // 输出: onClick
HandlerName的结果是'onClick' | 'onChange'。- 官方文档:Template Literal Types
注意事项
- 日常类型标注应使用
string,不要使用包装对象类型String。 const name = 'Tom'通常推断为字面量类型'Tom';let name = 'Tom'通常会拓宽为string。String(value)可将值转换为字符串;模板字符串中的插值也会触发字符串转换。
类型推断与字面量类型总结
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 只能精确表示整数,不能直接解决小数精度问题。误区:String 和 string 可以在类型标注中随意替换。
正确理解:string 是字符串原始类型,String 是包装对象类型,日常开发应使用小写形式。误区:类型标注能够改变 JavaScript 的运行时行为。
正确理解:TypeScript 类型主要在编译阶段提供检查,最终的数值精度、类型转换和运算行为仍由 JavaScript 决定。
到此这篇关于TypeScript 中number、bigint与 string的文章就介绍到这了,更多相关TypeScript number bigint string内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
