Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
567 views
in Technique[技术] by (71.8m points)

dictionary - How to use enum as index key type in typescript?

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());

Also in playground

There are 3 issues/questions with it:

  1. Why I cannot omit properties in my initializer literal, even though I declare properties as '| undefined'
  2. Why I cannot use 'DialogType.Options' as type key, and have to use hardcoded number instead?
  3. Why do I have to use 'key in DialogType' instead of 'key: DialogType'? (Or can I? )
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  1. |undefined does not make a property optional, just means it can be undefined, 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 }
    
  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; }
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...