Typescript:括号表示法属性访问

And*_*ski 11 typescript

我想访问带括号表示法的类型对象,如下所示:

interface IFoo {
    bar: string[];
}

var obj: IFoo = { bar: ["a", "b"] }
var name = "bar";
obj[name]. // type info lost after dot 
Run Code Online (Sandbox Code Playgroud)

据我所知,根据规范 4.10,它是一种预期的行为:

A bracket notation property access of the form ObjExpr [ IndexExpr ]  
....  
Otherwise, if IndexExpr is of type Any, the String or Number primitive type, or an enum type, the property access is of type Any.
Run Code Online (Sandbox Code Playgroud)

任何人都可以确认这是否属实,是否有可能绕过这种行为.

编辑: 我的用例是对象缩小,如

var props = {long_name: "n"};    
var shortName = props.long_name;

function(minObj) {
    var value = minObj[shortName]
    var newMinObj = {};
    newMinObj[shortName] = value.toUpperCase();
    db.save(newMinObj)
}
Run Code Online (Sandbox Code Playgroud)

Son*_*oul 27

我将它添加为一个单独的界面,因为我需要保持原来的..

export interface IIndexable {
  [key: string]: any;
}
Run Code Online (Sandbox Code Playgroud)

并在需要时引用它

getEditDate(r: IRestriction, fieldName: string) {
    ...
    value={(r as IIndexable)[fieldName] as Date}
Run Code Online (Sandbox Code Playgroud)

效果很好。如果我找到缩短它的方法,我会更新

  • 伟大的!我将其设为通用以保持类型安全:`export interface IIndexable<T = any> { [key: string]: T }` (5认同)

mk.*_*mk. 6

不用在中使用变量obj[x]您可以编写

obj["bar"].sort
Run Code Online (Sandbox Code Playgroud)

在此处使用变量的唯一原因是从IFoo界面中选择任意属性。您似乎只有一个。如果您的上有许多字符串数组IFoo,则可以使其可索引并编写:

interface IFoo {
    bar: string[];
    bar2: string[];
    [key: string]: string[]; // IFoo is indexable; not a new property
}
Run Code Online (Sandbox Code Playgroud)

这将使您可以编写:

var name = "bar";
obj[name].sort;
Run Code Online (Sandbox Code Playgroud)

但这也可以让您编写:

obj["some new property"] = ["a", "b"];
obj["some new property"].sort;
Run Code Online (Sandbox Code Playgroud)

  • 这将是一个相当复杂的推论(在大多数情况下它不起作用,在其他情况下它也没有用)。TypeScript 不执行它。通常,在某种语言中无法或难以以某种方式做事表明,用该语言做事的方式很糟糕(至少因为人们会不熟悉它,尽管通常这实际上是不合适的并且是一个坏主意) 。 (2认同)