类型 `{ [key in string]: boolean };` 和 `{ [key : string]: boolean };` 是否等效?

Bor*_*nth 8 typescript

反应选择中我偶然发现了这条线

export type SelectComponentsProps = { [key in string]: any };
Run Code Online (Sandbox Code Playgroud)

我从 这里 知道

type Keys = 'option1' | 'option2';
type Flags = { [K in Keys]: boolean };
Run Code Online (Sandbox Code Playgroud)

相当于

type Flags = {
    option1: boolean;
    option2: boolean;
}
Run Code Online (Sandbox Code Playgroud)

我也从 这里知道 会{ [key: string]: boolean; };对此感到满意:

let map : { [key: string]: boolean} = {};
map["foo"] = true;
map["bar"] = false;
map["foobar"] = "foo"; // Throws exception
map[1] = true; // Curiously doesn't throws exception
map.foo = true; // Throws exception
Run Code Online (Sandbox Code Playgroud)

那么,{ [key in string]: boolean };相当于{ [key : string]: boolean };?

如果不是,那{ [key in string]: boolean };意味着什么?

Nin*_*liu 9

正如您所展示的,确实可以观察到一些差异,如下所示

type T1 = {[key: string]: null};
type T2 = {[key in string]: null};

const t1: T1 = {'foo': null, 10: null};
const t2: T2 = {'foo': null, 10: null};

type S1 = keyof T1; // string | number
type S2 = keyof T2; // string

const s1: S1 = 10;
const s2: S2 = 10; // error
Run Code Online (Sandbox Code Playgroud)

TS 游乐场链接

另请注意,一种语法接受可选键,但不接受另一种:

type T1 = {[key: string]: null};
type T2 = {[key in string]: null};

type T1opt = {[key: string]?: null}; // invalid syntax
type T2opt = {[key in string]?: null};
Run Code Online (Sandbox Code Playgroud)

TS 游乐场链接

最后,使用in显然允许自引用,如@types/styled-components/index.d.ts#24中所示:

// This is "[key in string]" and not "[key: string]" to allow CSSObject to be self-referential

  • 有趣的是,quickinfo intellisense(将鼠标悬停在 VSCode 或 The Playground 等编辑器中的类型上以查看更多信息)将“{[x in string]: X}”显示为“{[x: string]: X}”。 (3认同)
  • 相关 GitHub 问题:[Microsoft/TypeScript#23592](https://github.com/microsoft/TypeScript/pull/23592)、[Microsoft/TypeScript#31013](https://github.com/microsoft/TypeScript/issues /31013) (2认同)