gpt4 book ai didi

typescript - 键入一个带有可选键的对象,但对于存在的键是非空值

转载 作者:行者123 更新时间:2023-12-04 12:11:11 24 4
gpt4 key购买 nike

我在 TypeScript 3.2.2 上使用 strict: true .

我一直无法键入具有一组动态定义的键的普通对象,但所有这些键都具有保证的非空值类型。

[TypeScript playground example]

// Will assume any property access has type T
interface Object<T> {
[key: string]: T;
}

// Will assume Object.values() could be undefined
interface Object<T> {
[key: string]: T | undefined;
}


// Doesn't compile
interface Object<T> {
[key: string]?: T;
}

最佳答案

正如评论中提到的,TypeScript 在 distinguishing missing properties from undefined properties 方面做得并不好。 .这至少在某种程度上是合理的,因为当您从 JavaScript 中的对象中读取缺失的属性时,您将得到 undefined (而不是错误)。和之前 --strictNullChecks compiler option是在 TypeScript 2.0 中引入的,TypeScript 在区分缺失/未定义的属性和存在/定义的属性方面做得非常糟糕。这主要是由 --strictNullChecks 解决的但有几个问题仍然存在。
此问题仍然出现的地方之一是 types with index signatures .索引签名仅被视为存在。无法通过索引签名来说明某些键存在而某些键不存在。 optional index signature你想要的语法不是语言的一部分。与 --strictNullChecks打开,签名{[k: string]: SomeType}是说每个字符串键属性都存在并且类型为 SomeType ,但是当您将对象分配给它时,这实际上并未强制执行。使用索引签名的唯一真正类型安全的方法是添加 | undefined到值类型,如 {[k: string]: SomeType | undefined} ,但这最终会在许多情况下变得非常烦人,导致人们过度使用非空断言,即 doesn't help anyone .所以就是这样。

TS4.1 更新
TS4.1 将引入 --noUncheckedIndexedAccess compiler option ,也称为“迂腐索引签名”,其行为大多类似于 | undefined已添加到索引签名中。以上述方式使用这仍然很烦人,尤其是对于字符串索引签名(数组不那么糟糕,因为您可以创建一个 for..of 循环,而不必担心 undefined ),因此该答案的其余部分主要是.

现在你的选择是,正如我所看到的:

  • 使用没有 | undefined 的索引签名并处理编译器认为所有属性都存在而有些属性不存在的事实(检查编译器认为不需要的属性,例如 if (unknownKey in foo) {... foo[unknownKey] ...} )
  • 使用带有 | undefined 的索引签名(或在 TS4.1+ 中使用 --noUncheckedIndexedAccess)并处理这样一个事实,即编译器不断警告您,当您知道某个值可能未定义时(执行您不需要的额外检查,例如 const prop = foo[knownKey]; if (typeof prop !== 'undefined') { ... prop ... } ;或非空断言,如 const prop = foo[knownKey]! )
  • 不要使用索引签名。您可能可以使用 mapped type 逃脱惩罚。其中键集是一些文字的联合,您在定义类型时不知道,但您会知道何时使用它。即,使用预定义的 Record<K, T> 类型:
      type Record<K extends keyof any, T> = {[P in K]: T};
    但是当试图操纵时这会变得更加复杂,所以我不会在这里深入探讨。

  • 不知道还有什么要说的。这是一个持续存在的语言限制,因为替代方案似乎更烦人。如果您有一个引人注目的用例,您可能可以对一些链接的 GitHub 问题发表评论或打开一个新的问题,但我不希望这里会有太大变化。
    哦哦,希望能帮到你。祝你好运!

    关于typescript - 键入一个带有可选键的对象,但对于存在的键是非空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54446157/

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