我想在Typescript对象中存储string ->字符串的映射,并强制所有值映射到字符串。例如:
var stuff = {};
stuff["a"] = "foo"; // okay
stuff["b"] = "bar"; // okay
stuff["c"] = false; // ERROR! bool != string
是否有一种方法让我强制值必须是字符串(或任何类型..)?
我想在Typescript对象中存储string ->字符串的映射,并强制所有值映射到字符串。例如:
var stuff = {};
stuff["a"] = "foo"; // okay
stuff["b"] = "bar"; // okay
stuff["c"] = false; // ERROR! bool != string
是否有一种方法让我强制值必须是字符串(或任何类型..)?
当前回答
你可以传递一个名字给未知键,然后写你的类型:
type StuffBody = {
[key: string]: string;
};
现在你可以在你的类型检查中使用它:
let stuff: StuffBody = {};
但对于FlowType,不需要有名称:
type StuffBody = {
[string]: string,
};
其他回答
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
interface AccountSelectParams {
...
}
const params = { ... };
const tmpParams: { [key in keyof AccountSelectParams]: any } | undefined = {};
for (const key of Object.keys(params)) {
const customKey = (key as keyof typeof params);
if (key in params && params[customKey] && !this.state[customKey]) {
tmpParams[customKey] = params[customKey];
}
}
如果你明白这个概念,请评论
实际上有一个内置的实用程序记录:
const record: Record<string, string> = {};
record['a'] = 'b';
record[1] = 'c'; // leads to typescript error
record['d'] = 1; // leads to typescript error
一个快速更新:自Typescript 2.1以来,有一个内置的类型Record<T, K>,它的作用类似于字典。
在这种情况下,你可以这样声明:
var stuff: Record<string, any> = {};
你也可以通过联合文字类型来限制/指定潜在的键:
var stuff: Record<'a'|'b'|'c', string|boolean> = {};
下面是一个使用文档中的record类型的更通用的例子:
// 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 }
TypeScript 2.1文档记录<T, K>
我认为使用{[key: T]: K}的唯一缺点是,你可以编码关于你使用什么类型的键来代替“key”的有用信息,例如,如果你的对象只有质键,你可以这样提示:{[prime: number]: yourType}。
下面是我写的一个正则表达式来帮助这些转换。这只会转换标签为“key”的情况。要转换其他标签,只需更改第一个捕获组:
查找: \{\s*\[(key)\s*(+\s*:\s*(\w+)\s*\]\s*:\s*([^\}]+?)\s*;?\s*\}
替换:记录<$ 2,$ 3>
定义接口
interface Settings {
lang: 'en' | 'da';
welcome: boolean;
}
强制键为设置界面的特定键
private setSettings(key: keyof Settings, value: any) {
// Update settings key
}