如何使用枚举作为索引键类型的类型?

考虑下面的例子。

enum DialogType {
Options,
Help
}


class Dialog {
test() : string {
return "";
}
}


class Greeter {


openDialogs: { [key in DialogType]: Dialog | undefined } = {
0: undefined,
1: undefined
};


getDialog(t: DialogType) {
return this.openDialogs[t];
}
}


const greeter = new Greeter();
const d = greeter.getDialog(DialogType.Help);
if (d) document.write(d.test());

也在操场上

有三个问题:

  1. 为什么我不能在初始值设定项文字中省略属性,即使我将属性声明为“ | 未定义”
  2. 为什么我不能使用‘ DialogType.Options’作为类型键,而必须使用硬编码的数字?
  3. 为什么我必须使用‘ key in DialogType’而不是‘ key: DialogType’? (或者我可以吗?)
113281 次浏览
  1. |undefined没有使一个属性成为可选的,只是意味着它可以是 undefined,有一个建议使 |undefined成员成为可选的,但目前还没有实现。您需要在 ]之后使用 ?来使所有属性成为可选的

    { [key in DialogType]?: Dialog }
    
  2. You can use the dialog enum values as keys, but they need to be computed properties:

    let openDialogs: { [key in DialogType]?: Dialog } = {
    [DialogType.Options]: undefined,
    };
    
  3. { [key: number or string]: Dialog } is an index signature. Index signatures are restricted to only number or string as the key type (not even a union of the two will work). So if you use an index signature you can index by any number or string (we can't restrict to only DialogType keys). The concept you are using here is called mapped types. Mapped types basically generate a new type based on a union of keys (in this case the members of DialogType enum) and a set of mapping rules. The type we created above is basically equivalent to:

    let o: { [DialogType.Help]?: Dialog; [DialogType.Options]?: Dialog; }