typescript 如何在打字稿中使用枚举作为索引键类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52700659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use enum as index key type in typescript?
提问by ironic
Consider following example.
考虑以下示例。
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());
There are 3 issues/questions with it:
它有 3 个问题/问题:
- Why I cannot omit properties in my initializer literal, even though I declare properties as '| undefined'
- Why I cannot use 'DialogType.Options' as type key, and have to use hardcoded number instead?
- Why do I have to use 'key in DialogType' instead of 'key: DialogType'? (Or can I? )
- 为什么我不能在初始化器文字中省略属性,即使我将属性声明为 '| 不明确的'
- 为什么我不能使用 'DialogType.Options' 作为类型键,而必须使用硬编码数字?
- 为什么我必须使用 'key in DialogType' 而不是 'key: DialogType'?(或者我可以吗?)
回答by Titian Cernicova-Dragomir
|undefined
does not make a property optional, just means it can beundefined
, there is a proposal to make|undefined
members optional but currently it's not implemented. You need to use?
after]
to make all properties optional{ [key in DialogType]?: Dialog }
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, };
{ [key: number or string]: Dialog }
is an index signature. Index signatures are restricted to onlynumber
orstring
as the key type (not even a union of the two will work). So if you use an index signature you can index by anynumber
orstring
(we can't restrict to onlyDialogType
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; }
|undefined
不使属性可选,只是意味着它可以undefined
,有一个建议使|undefined
成员可选,但目前尚未实现。您需要使用?
after]
使所有属性可选{ [key in DialogType]?: Dialog }
您可以使用对话框枚举值作为键,但它们需要计算属性:
let openDialogs: { [key in DialogType]?: Dialog } = { [DialogType.Options]: undefined, };
{ [key: number or string]: Dialog }
是一个索引签名。索引签名仅限于number
或string
作为键类型(甚至两者的联合都不起作用)。因此,如果您使用索引签名,则可以通过任何number
或string
(我们不能仅限于DialogType
键)进行索引。您在此处使用的概念称为映射类型。映射类型基本上基于键的联合(在本例中为 DialogType 枚举的成员)和一组映射规则生成新类型。我们上面创建的类型基本上相当于:let o: { [DialogType.Help]?: Dialog; [DialogType.Options]?: Dialog; }