typescript - 自动推断变量属于键集中

标签 typescript

我有一个对象并想使用字符串变量访问它,但是我收到错误:

no index signature with a parameter of type 'string' was found on type '{ A: number; B: number; C: number; }'

const obj = {
    "A":1,
    "B":2,
    "C":3
 }

 const f=(str:string)=>{
     const result = obj[str];
 }

但是,这个编译和结果不应该具有number|undefined类型吗?解决这个问题的唯一方法是将 str 转换为 keyof typeof obj,如所述 here ?我还想过这样做 if (Object.keys(obj).includes(str))... 但这并没有将 str 的类型缩小为仅有效键。

最佳答案

TypeScript 中的对象类型是“开放”或“可扩展”,而不是“封闭”或“精确”。对象类型的值需要具有已知的属性,但通常不禁止具有额外的未知属性。开放且可扩展的对象类型非常有用:它们允许接口(interface)和类扩展形成类型层次结构;所以 interface Bar extends Foo { extraProp: string } 意味着每个 Bar 也是 Foo ,尽管 Foo 的定义不知道关于 extraProp 的任何信息。但它确实产生了让开发人员感到惊讶的影响。目前还没有真正支持确切的类型(尽管 excess property checking 确实有时看起来不是这样);请参阅 microsoft/TypeScript#12936 了解相关功能请求。

让我们检查一下编译器推断的 obj 的类型:

/* const obj: {
    A: number;
    B: number;
    C: number;
} */

这意味着编译器知道 obj 在键 ABC 处具有数字属性。但由于对象类型是开放的,编译器不知道缺少所有其他属性。尽管分配给 obj 的对象文字确实缺少任何其他属性,但类型系统不会跟踪此类信息。就编译器而言,obj 可能有也可能没有各种其他属性。它只会让你在没有警告的情况下访问 ABC (无论如何都是 --strict--noImplicitAny ),但是如果你用一些未知的 string 键对其进行索引,编译器会说“那可能是 any ” ”。

TypeScript 可以指定未知属性类型的最接近方法是使用 index signature ,例如 {[k: string]: number | undefined}

您不能说“ABC 的类型为 number 并且所有其他属性均为 undefined ”,因为这需要不同类型的索引签名来表示“所有其他属性”(有关相关功能,请参阅 microsoft/TypeScript#17867要求)。相反,您可以说“ABCnumber所有属性都是 number | undefined 。或者,如果您并不真正关心跟踪 AB ,和 C ,你可以这样做上面提到的“所有属性都是 string | undefined 通过以下类型注释:

const obj: {[k: string]: number | undefined} = {
    "A": 1,
    "B": 2,
    "C": 3
};

const f = (str: string) => {
    const result = obj[str]; // number | undefined
}

现在您的函数将返回 number | undefined ,如您所愿。

Playground link to code

关于typescript - 自动推断变量属于键集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65874824/

相关文章:

html - 使用 tsify (Typescript) 时,需要 HTML 文件作为 Browserify 中的模板字符串

typescript - 如何为 fabric 安装 .d.ts

javascript - 如何获取特定位置和特定标签的 Instagram 帖子数量

javascript - Flex 与 HTML5/TypeScript 之间的通信

javascript - typescript :对象可能是 'undefined'

angular - 如何在 Angular 组件中测试 ViewChild/ContentChild 属性?

angular - 何时使用 RxJS Observable<Object[]> 和 Observable<Object>?

angular typescript 接口(interface)默认值

TypeScript:联合类型上的对象可能为空

Typescript:在这种情况下如何使用泛型类型输入函数?