typescript - 如何创建具有可选值的接口
问题描述
我有一个对象,一开始我不知道其中会有什么键,但打字稿似乎没有考虑键的值可能不存在的可能性:
interface ById {
[key:string]: number[]
}
const test: ById = {
dummyValue: [1,2,3]
}
const doThing = (key: string) => {
// regardless of if this key exists, it still assumes it's an array
test[key].push(4)
}
doThing('test')
我想我会创建一个接口,明确表明该项目的值可能未定义,因此如果我不检查它是否存在,它会显示错误,但由于某种原因,它会显示错误,即使我检查。
interface ByIdOptional {
[key:string]: number[] | undefined
}
const test: ByIdOptional = {
dummyValue: [1,2,3]
}
const doThing = (key: string) => {
if (typeof test[key] !== 'undefined') {
// Even though I'm testing for undefined, it's showing an error here
test[key].push(4)
}
}
doThing('test')
有没有更好的方法来实现这一点,并获得使用该对象的类型安全代码?我也将代码添加到了 Typescript Playground(用于测试)
解决方案
您| undefined
的索引签名值类型是个好主意;现在,令人难以置信的假设索引签名类型在每个键上都有定义的值。undefined
编译器总是期望索引签名中的可能值更正确但可能令人讨厌。有一个开放的 GitHub 问题跟踪此问题(microsoft/TypeScript#13778),但我预计不会很快发生任何变化。
您检查的问题是编译器实际上没有办法跟踪typeof test[key] !== 'undefined'
. 该变量key
只知道是类型string
。编译器可以做的唯一可能的缩小范围是说“所有string
值的键test
都已被验证不是undefined
”。这不是一个理想的缩小范围,所以编译器基本上什么都不做。有一个关于此的 GitHub 问题文件 ( microsoft/TypeScript#31445 ),该文件作为设计限制已关闭。为了解决这个问题,语言必须跟踪哪些单独的变量被用作类型保护中的键,这对于它偶尔提供的帮助来说是很多额外的工作。
这里最简单的解决方法是将有问题的值复制到一个新变量中,可以通过控制流分析进行检查,而不必担心重新进行属性访问:
const doThing = (key: string) => {
const testKey = test[key];
if (typeof testKey !== 'undefined') {
testKey.push(4)
}
}
好的,希望有帮助;祝你好运!
推荐阅读
- python - tkinter 在 python 3.7 下无法识别
- php - 检查 strg 中的相同字符并从 PHP 中的下划线中删除和拆分?
- python - Python 在列表中搜索部分匹配项
- scala - Scala:如何在复制文件的函数上动态指定条件
- java - 如何将变量传递给扩展类的方法
- kotlin - 在另一个文件中实现 Kotlin 接口
- python - 确保我在每个请求中得到的推文在 twitter API 中是不同的?
- python - 正则表达式忽略特殊字符,但我需要连续四位数字,中间没有特殊字符
- date - Grails dataBinding 在默认编组 grails 日期上不起作用
- winforms - 如何使用 CefSharp winforms 接收拖动移动和拖放事件