TypeScript报表对象在不应该的情况下可能是“未定义”的

时间:2019-07-10 18:55:55

标签: javascript typescript

我试图理解为什么TypeScript给我以下错误:Object is possibly 'undefined'

这是代码段:

    const mergedDepsObj: { [key: string]: string } // Implementation here is not important

    const results: Map<string, number> = new Map();

    Object.keys(mergedDepsObj).forEach((key: string) => {
      results.has(key) ? results.set(key, results.get(key) + 1) : results.set(key, 0);
    })

基本上,当我尝试增加Map中的值时(结果),我在此行results.set(key, results.get(key) + 1)上收到该错误

它不应该对我大喊大叫,因为我正在检查该值是否首先存在。 也许我想念什么?

谢谢

3 个答案:

答案 0 :(得分:3)

Map.has() See this issuethis issue没有类型防护。

您可以通过回退0-1或您认为最适合您的代码的方式来解决此问题。

const mergedDepsObj: { [key: string]: string } = {}
const results: Map<string, number> = new Map();
Object.keys(mergedDepsObj).forEach((key: string) => {
  results.has(key) ? results.set(key, (results.get(key) || 0) + 1) : results.set(key, 0);
})

自定义类型防护

但是,如上所述,我们在this comment的帮助下创建了自己的类型保护。

interface Map<K, V> {
    // Works if there are other known strings.
    has<KnownKeys extends K, CheckedString extends K>(this: MapWith<string, V, any>, key: CheckedString): this is MapWith<K, V, CheckedString | KnownKeys>

    has<CheckedString extends K>(this: Map<string, V>, key: CheckedString): this is MapWith<K, V, CheckedString>
}

interface MapWith<K, V, DefiniteKey extends K> extends Map<K, V> {
    get(k: DefiniteKey): V;
}

const mergedDepsObj: { [key: string]: string } = {}
const results: Map<string, number> = new Map();

Object.keys(mergedDepsObj).forEach((key: string) => {
    results.has(key) ? results.set(key, results.get(key) + 1) : results.set(key, 0);
})

我们可以在操作中here看到它

答案 1 :(得分:0)

如果您查询不在地图中的键,则将无法定义。不是因为映射包含未定义的值,而是因为它根本不包含任何值。

尝试

results.get(key)!

results.get(key)作为数字

答案 2 :(得分:0)

因为编译器考虑到Map的行为并不聪明。