实施Typescript对象的索引成员的types?

我想在string对象中存储string – >string的映射,并强制所有的键映射到string。 例如:

var stuff = {}; stuff["a"] = "foo"; // okay stuff["b"] = "bar"; // okay stuff["c"] = false; // ERROR! bool != string 

有没有办法强制我的值必须是string(或任何types的..)?

 var stuff: { [s: string]: string; } = {}; stuff['a'] = ''; // ok stuff['a'] = 4; // error // ... or, if you're using this a lot and don't want to type so much ... interface StringMap { [s: string]: string; } var stuff2: StringMap = { }; // same as above 

无论我走到哪里,我都随身带着这个文件

 export interface IStringTMap<T> { [key: string]: T; }; export interface INumberTMap<T> { [key: number]: T; }; export interface IStringAnyMap extends IStringTMap<any> {}; export interface INumberAnyMap extends INumberTMap<any> {}; export interface IStringStringMap extends IStringTMap<string> {}; export interface INumberStringMap extends INumberTMap<string> {}; export interface IStringNumberMap extends IStringTMap<number> {}; export interface INumberNumberMap extends INumberTMap<number> {}; export interface IStringBooleanMap extends IStringTMap<boolean> {}; export interface INumberBooleanMap extends INumberTMap<boolean> {}; 

IStringTMapINumberTMap是generics,可用于创build任何types的映射(通过let myTypeMap: IStringTMap<MyType> = {} )。 其余的是常用字面types之间有用的预先定义的映射。

这里重要的语法是{ [key: string]: T; } { [key: string]: T; }这表示接口使用stringtypes的键(字key可以是任何标识符,并且应该用于指示键的重要性)和typesT值强制对象文字。 如果你想用string键和boolean值来构造一个对象(而不是使用上面的inheritance),那么接口就是{ [key: string]: boolean }

@Ryan Cavanaugh的回答完全正确,依然有效。 还有值得补充的是,从16年秋季开始,当我们可以宣称大多数平台都支持ES6时,只要需要将某些数据与某个关键字关联起来,坚持使用Map几乎总是更好。

当我们写let a: { [s: string]: string; } let a: { [s: string]: string; }我们需要记住,编译后的字典没有types数据这样的东西,它只用于编译。 和{[s:string]:string; }将编译为{}。

这就是说,即使你会写如下的东西:

 class TrickyKey {} let dict: {[key:TrickyKey]: string} = {} 

这只是不会编译(即使对于target es6 ,您将得到error TS1023: An index signature parameter type must be 'string' or 'number'.

所以,实际上你被限制为string或数字作为潜在的关键,所以在这里没有太多的强制types检查的意义,特别是要记住,当js试图通过数字访问键将其转换为string。

所以假设最好的做法是使用Map,即使键是string也是很安全的,所以我坚持:

 let staff: Map<string, string> = new Map(); 

build立在@ shabunc的答案上,这将允许强制执行键或值(或者两者)是任何你想强制执行的。

 type IdentifierKeys = 'my.valid.key.1' | 'my.valid.key.2'; type IdentifierValues = 'my.valid.value.1' | 'my.valid.value.2'; let stuff = new Map<IdentifierKeys, IdentifierValues>(); 

还应该使用enum而不是type定义。