提问人:natevw 提问时间:7/26/2023 更新时间:7/26/2023 访问量:49
为什么 TypeScript 不根据使用变量键的检查来缩小范围?
Why doesn't TypeScript narrow based on checks using a variable key?
问:
如果我的代码大致如下:
const obj: Record<string, SomeType>;
if ("key" in obj) {
const val: SomeType = obj["key"];
void val;
}
TypeScript 编译器并没有让我对 .val
同样,如果我编写这样的代码:
const val = obj["key"];
if (val) {
const val2: SomeType = val;
void val2;
}
TypeScript 编译器知道 / 不能在检查中。val
val2
| undefined
但是,如果我编写这样的代码:
let k = "key";
if (obj[k]) {
const val: SomeType = obj[k];
void val;
}
然后 TypeScript 抱怨说,这仍然可能是.val: Sometype
| undefined
即使我在与上一个有点相似的情况下使用 a,它仍然不满意:const
(["a", "b", "c"]).forEach(_k => {
const k = _k;
if (obj[k]) {
const val: SomeType = obj[k];
// ^^^ VSCode still thinks it could be `| undefined`!
}
});
为什么会这样?
答:
0赞
Linden Wells
7/26/2023
#1
我不太擅长使用类型进行推理,但是在您的第三个块中,更改为 a 会使类型起作用:k
const
const k = "key";
if (obj[k]) {
const val: string = obj[k];
void val;
}
这并不能解决您的问题,但您可以断言数组是内联的。
第四个代码块我只能通过添加一个中间步骤来进行类型检查:const
(["a", "b", "c"] as const).forEach(k => {
const val = obj[k] as const
if (val) {
const narrowed_val: string = val;
}
});
希望这能帮助你继续你正在做的任何事情,但希望更聪明的打字稿推理者可以准确地解释发生了什么。
注意我把你改成了,以便更容易在vscode中使用。SomeType
string
评论
1赞
natevw
7/26/2023
谢谢,是的,不幸的是,这些变体确实出于某种原因起作用,但其他变体不起作用!更多的是我试图修复的循环本身,并不真正需要那个,但它为什么不能工作仍然是一个谜。let k
0赞
Linden Wells
7/26/2023
我在 jcalz 的评论中查看了 TS 问题,但阅读了以下回复: github.com/microsoft/TypeScript/issues/51368
0赞
jcalz
7/26/2023
“阅读回复”是什么意思?您能明确说明您想让我们注意什么吗?
0赞
Linden Wells
7/26/2023
>是的,foo[“bar”] 曾经是不可缩小的。现在是,但 foo[keyVar] 不缩小的更大问题仍然存在(在实现方面,这是一个更大的蠕虫罐头)。取自 github.com/microsoft/TypeScript/issues/...
0赞
jcalz
7/26/2023
是的,ms/TS#10530 是他们跟踪更大问题的地方,即使问题的名称不再适用。不知道为什么他们既不更改名称以反映这一点,也不关闭它以支持单独的问题。因此,每当我谈论更大的问题时,我都会很高兴地将人们指向 ms/TS#10530,然后必须进行这种额外的对话,讨论它如何真正成为关注更大问题更新的地方,尽管有这个名字。太好玩了,呜呜。
评论
obj[key]
key
obj[key1]
obj[key2]
key1
key2
"key"
let k = "key"
const k = "key"
const k = _k: "a" | "b" | "c"
let k = "key"
k
string
const k = "key"
"key"
const k = _k: "a" | "b" | "c"
const k: "a" | "b" | "c" = _k
_k