【问题标题】:Need TypeScript annotation to access object property via a variable需要 TypeScript 注释才能通过变量访问对象属性
【发布时间】:2019-12-06 20:10:34
【问题描述】:

在纯 JavaScript 中,我们可以使用变量读取对象属性的值。

也就是说,这是有效的:

let obj = { a: 100, b: 'Need help with TypeScript', c: new Date() };
let prop = 'b';
console.log( obj[prop] );  // Need help with TypeScript

但是,以下将 prop 声明为字符串的 TypeScript 注释会导致指示的索引错误。

let obj: object = { a: 100, b: 'Need help with TypeScript', c: new Date() };
let prop: string = 'b';
console.log( obj[prop] );  // TypeScript error element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.

我应该如何注释上面的内容?

2019 年 12 月 9 日编辑:当我发布问题时,我假设会有一个通用答案,而不是一个明确依赖于我的示例对象的答案。

我的用例是一个函数,它接受属性名称作为参数。该函数根据传递的属性名称对数组进行排序。我移植到 TS 的原始 JavaScript 代码将对任何对象数组进行排序。

【问题讨论】:

  • 根本不要注释obj;让它被推断为类型{a: number, b: number, c: number}。至于prop,你也不需要注解,但你要么把let改成const,要么用let prop = "b" as const,比如this
  • @jcalz - 感谢您的评论和示例。我查看了示例并且它有效,但我不明白它为什么有效。为什么将属性声明为 const 会有所不同。对于我的具体情况,我还没有机会尝试您的建议。我会的。 (请参阅我今天所做的修改。)
  • "为什么将属性声明为const 会有所不同" 编译器将const 视为表明该值不会改变的意图(这仅适用于原语,但无论如何) , 所以它推断它是一个更窄的类型。如果您写let prop = "b",它猜测您希望prop 成为string,因为您可能稍后将其更改为其他string。如果你写const prop = "b",它知道prop 永远是"b",所以它推断出字符串文字类型"b"。如果它满足您的需求,我很乐意将其转化为答案。

标签: typescript


【解决方案1】:

避免object作为类型,TS不能从中推断出做什么。

考虑添加一个类型,允许你做你想做的事:

let obj: { [key: string]: number } = { a: 100, b: 200, c: 300 };
let prop: string = 'b';
console.log( obj[prop] );

您甚至可以使用[key in type] 语法进一步细化,其中 type 是类型定义:

type props = 'a' | 'b' | 'c';
let obj: { [key in props]: number } = { a: 100, b: 200, c: 300 };
let prop: props = 'b';
console.log(obj[prop]);

稍后可以通过使用接口来简化对命名属性的访问。以此为基础,keyof 运算符非常有帮助:

interface IProps{
  a: number,
  b: number,
  c: number
}
let obj: { [key in keyof IProps]: number} = { a: 100, b: 200, c: 300 };
let prop: keyof IProps = 'b';
console.log(obj[prop]);

最后一个更多的是用于演示、参考和展示,而不是 OP 正在寻找的完美答案。

【讨论】:

    猜你喜欢
    • 2014-04-25
    • 2021-05-21
    • 1970-01-01
    • 2012-02-04
    • 2019-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多