我有以下类型的护卫:
enum X {
A = "1"
}
const isNullableX = (value: any): value is X | null => false
let foo: string | null = ''
if (isNullableX(foo)) {
console.log(foo)
}我希望上一个console.log中的console.log类型是X | null,但它只是X。有人能给我解释一下这是怎么回事吗?如果我将foo的声明更改为let foo: unknown = '',则正确推断console.log中的类型。
下面是一个要使用的示例:游乐场
发布于 2022-04-13 19:37:50
TypeScript使用控制流分析来更具体地表示表达式的明显类型窄。例如,当您赋值到联合型的一个变量时,它将把变量的类型缩小到那些为该值工作的联合成员,至少直到下一个赋值为止。因此,对于这一点:
let foo: string | null = ''
foo // string编译器已经将foo从string | null缩小到了string。编译器知道,在分配之后,foo不是null。(如果您将其更改为let foo = Math.random()<0.5 ? '' : null,则分配范围不会缩小,事情可能会像您以后预期的那样发生。)
控制流分析将缩小表达式的明显类型,或者将该类型重新设置为带注释的类型或原始类型。你不能现实地做的是任意地扩大一个类型,或者将一个类型变异成一些无关的东西。
当你像这样调用一个用户定义类型保护功能
const isNullableX = (value: any): value is X | null => false它将根据输出缩小输入类型。在你的电话里:
if (isNullableX(foo)) {
foo // X
}您正在将foo从string缩小到可分配给X | null的内容。这里唯一可信的结果是X,因为null不能分配给string。因此,foo被缩小为X。如果你期望foo会从string变成X | null,那是不可能的,因为这是一种任意的突变(我想这可能是一个重置-然后-a-缩小,但没有重置,因为没有重新分配)。
发布于 2022-04-13 11:17:51
这个怎么样..。
enum X {
A = "1"
}
function assertIsTrue(condition: unknown): asserts condition is boolean {
if (!condition) {
throw new Error("Not True!");
}
}
const isNullableX = (value: any): value is X | null => false
let foo = '' as string | null;
assertIsTrue(isNullableX(foo));
console.log(foo);https://stackoverflow.com/questions/71855286
复制相似问题