我想在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
}