gpt4 book ai didi

typescript - 解构空数组时,TS 不会推断可能未定义

转载 作者:行者123 更新时间:2023-12-04 13:14:07 24 4
gpt4 key购买 nike

在查看解构元素的推断类型时,它会假设数组永远不会为空。

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

console.log(first); // undefined

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


Playground Link

这导致了一个有趣的行为,例如 TSLint 规则“严格类型谓词”,它将 if 语句标记为始终为真,而实际上并非如此。

我错过了什么,这是正常行为吗?

最佳答案

TypeScript 4.1 更新undefined 仍然是预期的行为不包括在索引签名属性的域中,原因如下。然而,由于这是一个经常被要求的功能,TypeScript 团队(有点不情愿?)让步并添加了 --noUncheckedIndexedAccess compiler flag .如果您启用它(默认情况下它既不启用,也不包含在 --strict 编译器标志中,因此您需要明确地这样做),您将开始获得您可能想要的行为。
请注意,这实际上与添加 undefined 并不完全相同。你自己。索引访问将添加 undefined :

// --noUncheckedIndexedAccess is enabled

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

console.log(first); // undefined

if (first !== undefined) {
first.toFixed(); // okay
}
但是 for..of循环和数组函数式编程方法仍然会像 undefined 一样工作是不可能的(即:好像稀疏数组不存在一样):
for (const n of x) {
n.toFixed(); // no error, yay!
}

x.map(n => n.toFixed()); // no error, yay!
因此,您可能想要启用该标志。请记住,一些常见的数组/字典操作技术可能仍然“令人讨厌”,这就是为什么它不是 --strict 的一部分的原因。家庭。
Playground link to code

原答案
这是预期的行为。见 microsoft/TypeScript#13778想要查询更多的信息。这个问题是请求允许索引签名属性类型自动包含 undefined在他们的领域中,虽然这个问题仍然存在,但很明显它不会被实现。见 this comment例如。
not a design goal of TypeScript (请参阅列表中的 #3)类型系统是否完美或正确(尽管当我们考虑太多时,像我这样的人会感到心痛;我之前开玩笑说要成立一个 TypeScript Unsoundness Support Group 来帮助人们处理它)。取而代之的是正确性和可用性之间的权衡。
语言维护者注意到,有很多现实世界的代码在没有检查可能的情况下索引到数组 undefined值无处不在,并且强制执行此检查会将简单的 for 循环变成执行检查或使用类型断言的乏味练习。问题是(参见 this comment )编译器无法轻易区分数组类型的安全索引和不安全索引之间的区别。因此,要么编译器假设该属性不是 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
好的,希望有帮助;祝你好运!
Playground link to code

关于typescript - 解构空数组时,TS 不会推断可能未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62135076/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com