TypeScript 类型拓宽(Type Widening)
- TypeScript 中的类型拓宽(Type Widening)是 TypeScript 编译器在推断变量类型时的一种行为。
- 它通常发生在使用 let 或 var 声明变量时,TypeScript 会将变量的类型推断为一个更宽泛的类型,而不是具体的字面量类型。这种行为是为了确保变量在后续可以被重新赋值为其他值。
- 如果使用 const 声明变量,TypeScript 不会拓宽类型,而是推断为具体的字面量类型。
1. 字面量类型的拓宽
let x = 10; // x 的类型被拓宽为 number,而不是字面量类型 10,因为Ts知道这个值后续会变所以类型被拓宽
x = 20; // 合法,因为 x 的类型是 number
- 如果使用 const 声明变量,TypeScript 不会拓宽类型,而是推断为具体的字面量类型:
const y = 10; // y 的类型是字面量类型 10
y = 20; // 报错,因为 y 的类型是 10,不能重新赋值
2. 字符串字面量的拓宽
let name = "Alice"; // name 的类型被拓宽为 string,而不是字面量类型 "Alice"
name = "Bob"; // 合法
如果使用 const:
const name = "Alice"; // name 的类型是字面量类型 "Alice"
name = "Bob"; // 报错
3. 布尔值的拓宽
let isActive = true; // isActive 的类型被拓宽为 boolean,而不是字面量类型 true
isActive = false; // 合法
如果使用 const:
const isActive = true; // isActive 的类型是字面量类型 true
isActive = false; // 报错
4. 对象属性的拓宽
- 对象的属性也会发生类型拓宽:
const obj = {
x: 10, // x 的类型被拓宽为 number
};
obj.x = 20; // 合法
- 如果希望对象的属性不被拓宽,可以使用显式类型注解:
const obj: { x: 10 } = {
x: 10, // x 的类型是字面量类型 10
};
obj.x = 20; // 报错
5. 数组的拓宽
- 数组中的元素类型也会被拓宽:
const numbers = [1, 2, 3]; // numbers 的类型被推断为 number[]
numbers.push(4); // 合法
- 如果希望数组中的元素不被拓宽,可以使用显式类型注解:
const numbers: [1, 2, 3] = [1, 2, 3]; // numbers 的类型是元组类型 [1, 2, 3]
numbers.push(4); // 报错
如何避免类型拓宽
- 使用 const 声明变量
- const 声明的变量不会被拓宽,TypeScript 会推断为具体的字面量类型。
- 使用显式类型注解
- 使用 as const 断言
- 使用 Readonly 或 readonly
类型拓宽的实际应用
- 当需要变量可以被重新赋值时。
但在某些场景下,可能需要避免类型拓宽,例如:
- 当需要精确的类型推断时。
- 当需要确保变量不会被重新赋值为其他值时。
总结
- 类型拓宽是 TypeScript 在推断变量类型时的一种行为,通常发生在使用 let 或 var 声明变量时。
- 使用 const、显式类型注解、as const 断言或 readonly 可以避免类型拓宽。
- 类型拓宽在某些场景下非常有用,但在需要精确类型推断时需要注意避免。

浙公网安备 33010602011771号