实施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> {};
IStringTMap
和INumberTMap
是generics,可用于创build任何types的映射(通过let myTypeMap: IStringTMap<MyType> = {}
)。 其余的是常用字面types之间有用的预先定义的映射。
这里重要的语法是{ [key: string]: T; }
{ [key: string]: T; }
这表示接口使用string
types的键(字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
定义。