TypeScript类型问题:基础类型为何可赋值给null?null赋值数字无报错?
关于TypeScript中null与基础类型赋值、类型兼容性的疑问解答
这俩问题其实都和TypeScript的**严格空值检查(strictNullChecks)**以及类型兼容性规则挂钩,咱们一步步拆解清楚:
1. 为什么number、string等基础类型可以赋值给null?
说白了,这是TypeScript默认配置带来的行为——默认情况下strictNullChecks是关闭的,这时候TS会把null和undefined当成所有类型的子类型。意思就是:任何类型的值都能赋值给null类型的变量,反过来null也能塞给任何类型的变量。举个简单例子:
let num: number = null; // 没报错(默认配置下) let str: string = null; // 同样不会报错
要是你开启了strictNullChecks,这种赋值直接就会红报错了——因为此时null是独立的类型,只能赋值给null或者unknown、any这类通吃的类型。
2. 为什么将string赋值给number时报错,但null赋值给number时不报错?
结合你给出的代码示例来看,核心还是类型兼容性和strictNullChecks的设置在起作用:
先把你的代码再贴一遍方便对照:
export type ArrayWithNumberOrString = Array<number | string>; export type ArrayWithNumberOrNull = Array<number | null>; function doSomethingWithNumbersOnly(array: number[]): number[] { return array; }; const numbersAndString: ArrayWithNumberOrString = [1, 2, 3, 'string']; const numbersAndNull: ArrayWithNumberOrNull = [1, 2, 3, null]; doSomethingWithNumbersOnly(numbersAndString); // 触发类型错误 doSomethingWithNumbersOnly(numbersAndNull); // 无类型错误
- 对于
Array<number | string>和number[]:string和number是完全不搭的基础类型,互相之间没有子类型关系,所以包含字符串的数组肯定没法赋值给只接受数字的数组,TS自然会报错提醒你。 - 对于
Array<number | null>和number[]:在默认关闭strictNullChecks的状态下,null是number的子类型,所以number | null这个联合类型是兼容number类型的——TS会觉得这个数组里的元素都能当number用(虽然运行时真遇到null可能出问题,但编译阶段不会拦你)。
要是你打开了strictNullChecks,那doSomethingWithNumbersOnly(numbersAndNull)也会立刻报错,因为此时null不再是number的子类型,这俩数组类型就完全不兼容了。
顺带提一句:这种默认行为是为了兼容早期的JS代码(毕竟JS里null随便赋值),但实际项目里真心建议开启strictNullChecks(最好直接开全strict模式),能提前揪出好多空值相关的坑。
内容的提问来源于stack exchange,提问作者blub
相关产品推荐
相关产品推荐

