gpt4 book ai didi

javascript - 作为对象键访问时无法推断类型

转载 作者:行者123 更新时间:2023-12-02 18:47:31 25 4
gpt4 key购买 nike

给出以下示例:

type Dictionary = {
[key: string] : string | undefined
}

function greet(name: string) {
return 'Hello ' + name + '!';
}

function callGreetError(key: string, d: Dictionary) {
if (typeof d[key] !== 'undefined') {
return greet(d[key]) // TS Error: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.Type 'undefined' is not assignable to type 'string'.(2345)
}
return key + ' is not in dictionary';
}

function callGreetNoError(key: string, d: Dictionary) {
const storedVal = d[key];
if (typeof storedVal !== 'undefined') {
return greet(storedVal) // Error goes away when value is stored in an external var.
}
return key + ' is not in dictionary';
}

我试图理解为什么在 callGreetErrorif block 内的 d[key] 类型未被推断为一个字符串,即使我明确告诉 TS 它不是未定义

为什么在 callGreetNoError 上将 d[key] 的值存储在外部变量 storedVal 上可以修复此错误。

最佳答案

基本上TS不会缩小computed property names的属性访问类型喜欢 key .

const d: Dictionary = {...};
const key = "foo";
const fooProp = d[key];

// using .length as string type check
d["foo"] !== undefined && d["foo"].length; // ✔
fooProp !== undefined && fooProp.length; // ✔
d[key] !== undefined && d[key].length; // error, possibly undefined

事实并非如此,因为 TS 进行了一些可变性检查并警告 d[key]在检查和使用之间,值可能会发生变化。例如,以下代码对于编译器来说完全没问题,但可能会在运行时抛出:

const testDict: Dictionary = {
get foo() { return Math.random() > 0.5 ? "hey" : undefined }
};

function callGreetError(d: Dictionary) {
// compiles fine, but throws error at run-time from time to time
if (d["foo"] !== undefined) d["foo"].length
}
callGreetError(testDict)

允许使用 control flow 适当缩小变量范围,TS必须清楚地知道,你指的是什么属性:通过带点符号的属性访问d.foo或使用括号符号和文字,如 d["foo"]

const storedVal = d[key] 的“技巧”有效,因为 TS 推断出 storedVal 的变量类型成为string | undefined 。由于控制流分析通常基于变量,因此编译器现在可以更轻松地缩小范围storedVal支票 undefined

Playground

关于javascript - 作为对象键访问时无法推断类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60035357/

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