我在这里阅读了多篇关于缩小TypeScriptobject
类型的帖子和问题。unknown
但我还没有找到这个具体的问题或解决方案。
我发现大多数解决方案都需要执行类似的操作。
const result: unknown = {
movieName: "test",
};
if (
typeof result === "object" &&
result !== null &&
"movieName" in result &&
typeof result.movieName === "string" // <-- Error Here
) {}
Run Code Online (Sandbox Code Playgroud)
错误指出
属性“movieName”在类型“object”上不存在
我如何缩小范围,以便它知道该unknown
事物是object
包含该属性的movieName
?如何访问result.movieName
类型unknown
?
编辑:也许这是不可能的?下面评论中的建议将其声明为 Record<string,unknown> 可能是每个GitHub 请求的唯一方法?
jca*_*alz 20
TypeScript 4.9 将引入对in
未列出属性的运算符缩小的支持,如microsoft/TypeScript#50666中实现的那样,作为对下面提到的microsoft/TypeScript#21732的修复。此时,上面的代码无需修改即可运行:
const result: unknown = {
movieName: "test",
};
if (
typeof result === "object" &&
result !== null &&
"movieName" in result &&
typeof result.movieName === "string" // <-- okay
) {
result.movieName.toUpperCase(); // <-- okay
}
Run Code Online (Sandbox Code Playgroud)
这是目前 TypeScript 中缺少的功能。有关相关功能请求,请参阅microsoft/TypeScript#21732 。现在,当您使用像 这样的in
运算符作为类型保护k in result
时,只有当 的类型result
是已知某些成员拥有密钥而其他成员没有的联合时,它才真正进行任何有意义的缩小。k
它不断言具有 key 的属性的存在k
。所以在你的情况下,类型result
只是object
(从unknown
),不会发生任何有意义的事情。
我有时使用的解决方法是编写自己的用户定义类型保护函数in
,该函数的行为方式符合我想要的行为方式。例如:
function hasKey<K extends string, T extends object>(
k: K, o: T
): o is T & Record<K, unknown> {
return k in o;
}
Run Code Online (Sandbox Code Playgroud)
k in result
现在,我不再写,而是写hasKey(k, result)
:
if (
typeof result === "object" &&
result !== null &&
hasKey("movieName", result) &&
typeof result.movieName === "string" // okay
) {
result.movieName.toUpperCase(); // okay
}
Run Code Online (Sandbox Code Playgroud)
这可以按照你想要的方式工作,并且可以说是你在这里可以得到的最接近类型安全的方式,至少在本地解决 microsoft/TypeScript#21732 之前是这样。
归档时间: |
|
查看次数: |
2610 次 |
最近记录: |