当重构空数组时,TS将不会推断出可能的未定义。

问题描述 投票:0回答:1

当看解构元素的推断类型时,会认为数组永远不会是空的。

const x: number[] = [];
const [first] = x; // first inferred as number

console.log(first); // undefined

if (first !== undefined) {
    // ...
}

游戏场链接

这就导致了一个有趣的行为,例如TSLint规则 "严格类型谓词",它会将if语句标记为永远为真,而事实上它不是。

我是不是遗漏了什么,这是正常的行为?

typescript typescript-typings destructuring type-safety
1个回答
2
投票

这就是预期的行为。请看 microsoftTypeScript#13778 以获取更多信息。 这个问题是要求允许索引签名属性类型自动包括 undefined 在他们的领域中,虽然这个问题仍未解决,但相当明确的是,它不会被实施。 见 此话 比如说。

它是 不是TypeScript的设计目标 (见列表中的第3条),让类型系统完全健全或正确(尽管像我这样的人在想得太多时感到心痛;我以前曾开玩笑说要成立一个TypeScript不健全支持组来帮助人们处理这个问题)。 相反,在正确性和可用性之间有一个权衡。

语言维护者注意到,有很多现实世界的代码,在没有检查可能的 undefined 的值,而且强制执行这个检查会把一个简单的for-loop变成一个乏味的工作,要么执行检查,要么使用类型断言。 问题是(见 此话),编译器不容易区分安全和不安全的索引进入数组类型。 所以,要么编译器假设该属性不会被称为 "安全索引"。undefined 当这个假设是错误的时候,编译器就会产生错误的负值,就像现在这样......。或者,假设该财产可能是 undefined 并在索引操作实际上是安全的情况下,编译器会出现误报。 语言维护者的论点是,这种假阳性会经常发生,以至于开发人员会条件反射地完全忽略这些错误,从而使它和目前的情况一样无用,同时更加烦人。 所以他们会让它保持现在的样子。 😢


如果你愿意,你可以随时添加 undefined 到元素类型,假设这样的问题在你的用例中更有可能出现。

const x: (number | undefined)[] = [];
const [first] = x; // number | undefined

console.log(first); // undefined

if (first !== undefined) {
    first.toFixed(); // okay
}

但请记住,如果你的用例遵循正常的模式,你会遇到烦人的情况。

for (const n of x) {
    n.toFixed(); // error, annoying
    if (typeof n !== "undefined") n.toFixed(); // okay
    n!.toFixed(); // okay
}

x.map(n => n.toFixed()); // error, annoying
x.filter((n): n is number => typeof n !== "undefined").filter(n => n.toFixed()); // okay
x.map(n => n!.toFixed()); // okay

好的,希望能帮到你;祝你好运

游戏场链接到代码

© www.soinside.com 2019 - 2024. All rights reserved.