Arm*_*age 214 typescript
我想在Typescript对象中存储string - > string的映射,并强制所有键映射到字符串.例如:
var stuff = {};
stuff["a"] = "foo"; // okay
stuff["b"] = "bar"; // okay
stuff["c"] = false; // ERROR! bool != string
Run Code Online (Sandbox Code Playgroud)
有没有办法让我强制执行值必须是字符串(或任何类型..)?
Rya*_*ugh 391
var stuff: { [key: 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 { [key: string]: string; }
var stuff2: StringMap = { };
// same as above
Run Code Online (Sandbox Code Playgroud)
San*_*ord 86
无论我走到哪里,我随身携带这个文件
export interface StringTMap<T> { [key: string]: T; };
export interface NumberTMap<T> { [key: number]: T; };
export interface StringAnyMap extends StringTMap<any> {};
export interface NumberAnyMap extends NumberTMap<any> {};
export interface StringStringMap extends StringTMap<string> {};
export interface NumberStringMap extends NumberTMap<string> {};
export interface StringNumberMap extends StringTMap<number> {};
export interface NumberNumberMap extends NumberTMap<number> {};
export interface StringBooleanMap extends StringTMap<boolean> {};
export interface NumberBooleanMap extends NumberTMap<boolean> {};
Run Code Online (Sandbox Code Playgroud)
StringTMap并且NumberTMap是泛型,可用于创建任何类型的地图(via let myTypeMap: StringTMap<MyType> = {}).其余的是常见文字类型之间有用的预定义映射.
这里的重要语法是{ [key: string]: T; }表示接口使用类型的键string(该单词key可以是任何标识符,并且应该用于指示键的重要性)和类型值来强制实施对象文字T.如果你想string为键和boolean值构造一个带有"名称" 的对象(而不是使用上面的继承),它的接口就是{ [name: string]: boolean }.
10.10.2018更新:
查看下面@dracstaxi的答案 - 现在有一个内置类型Record,它或多或少地完成了这个.
dra*_*axi 57
快速更新:自Typescript 2.1以来,内置类型Record<T, K>就像字典一样.
来自docs的一个例子:
// For every properties K of type T, transform it to U
function mapObject<K extends string, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U>
const names = { foo: "hello", bar: "world", baz: "bye" };
const lengths = mapObject(names, s => s.length); // { foo: number, bar: number, baz: number }
Run Code Online (Sandbox Code Playgroud)
我看到使用它的唯一缺点{[key: T]:K是你可以编码关于你使用什么类型的键来代替"键"的有用信息,例如,如果你的对象只有你可以暗示的主键那样:{[prime: number]: yourType}.
这是我为帮助完成这些转换所写的正则表达式.这只会转换标签为"key"的情况.要转换其他标签,只需更改第一个捕获组:
找: \{\s*\[(key)\s*(+\s*:\s*(\w+)\s*\]\s*:\s*([^\}]+?)\s*;?\s*\}
更换: Record<$2, $3>
Iva*_*nko 39
实际上有一个内置实用程序 Record:
const record: Record<string, string> = {};
record['a'] = 'b';
record[1] = 'c'; // leads to typescript error
record['d'] = 1; // leads to typescript error
Run Code Online (Sandbox Code Playgroud)
定义接口
interface Settings {
lang: 'en' | 'da';
welcome: boolean;
}
Run Code Online (Sandbox Code Playgroud)
强制 key 为 Settings 界面的特定 key
private setSettings(key: keyof Settings, value: any) {
// Update settings key
}
Run Code Online (Sandbox Code Playgroud)
@Ryan Cavanaugh的回答完全没问题且仍然有效.值得一提的是,截至2016年秋季,当我们声称ES6得到了大多数平台的支持时,无论何时需要将某些数据与某些键相关联,最好坚持使用Map.
当我们编写时,let a: { [s: string]: string; }我们需要记住,在编译打字稿后,不存在类型数据这样的东西,它只用于编译.并且{[s:string]:string; 将编译为{}.
也就是说,即使你写的东西如下:
class TrickyKey {}
let dict: {[key:TrickyKey]: string} = {}
Run Code Online (Sandbox Code Playgroud)
这只是不会编译(即使是target es6,你会得到error TS1023: An index signature parameter type must be 'string' or 'number'.
所以实际上你被限制为字符串或数字作为潜在的密钥所以在这里没有那么多强制类型检查的意义,特别要记住,当js尝试按编号访问密钥时,它将其转换为字符串.
因此,假设最佳实践是即使键是字符串也使用Map是非常安全的,所以我坚持:
let staff: Map<string, string> = new Map();
Run Code Online (Sandbox Code Playgroud)
您可以将名称传递给未知键,然后编写您的类型:
type StuffBody = {
[key: string]: string;
};
Run Code Online (Sandbox Code Playgroud)
现在您可以在类型检查中使用它:
let stuff: StuffBody = {};
Run Code Online (Sandbox Code Playgroud)
但是对于FlowType不需要有名字:
type StuffBody = {
[string]: string,
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
149288 次 |
| 最近记录: |