web-dev-qa-db-fra.com

Comment utiliser l'énumération comme type de clé d'index en tapuscrit?

Considérez l'exemple suivant.

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

également dans l'aire de jeux

Il y a 3 problèmes/questions avec:

  1. Pourquoi je ne peux pas omettre des propriétés dans mon littéral d'initialisation, même si je déclare des propriétés comme '| indéfini'
  2. Pourquoi ne puis-je pas utiliser "DialogType.Options" comme clé de type et dois-je utiliser un numéro codé en dur à la place?
  3. Pourquoi dois-je utiliser "clé dans DialogType" au lieu de "clé: DialogType"? (Ou puis-je?)
11
ironic
  1. |undefined ne rend pas une propriété facultative, signifie simplement qu'elle peut être undefined, il est proposé de faire |undefined membres facultatifs mais actuellement il n'est pas implémenté. Vous devez utiliser ? après ] pour rendre toutes les propriétés facultatives

    { [key in DialogType]?: Dialog }
    
  2. Vous pouvez utiliser les valeurs d'énumération de boîte de dialogue comme clés, mais elles doivent être des propriétés calculées:

    let openDialogs: { [key in DialogType]?: Dialog } = {
        [DialogType.Options]: undefined,
    };
    
  3. { [key: number or string]: Dialog } est une signature d'index. Les signatures d'index sont limitées à seulement number ou string comme type de clé (même une union des deux ne fonctionnera pas). Donc, si vous utilisez une signature d'index, vous pouvez indexer par n'importe quelle number ou string (nous ne pouvons pas nous limiter aux seules clés DialogType). Le concept que vous utilisez ici est appelé types mappés. Les types mappés génèrent essentiellement un nouveau type basé sur une union de clés (dans ce cas, les membres de l'énumération DialogType) et un ensemble de règles de mappage. Le type que nous avons créé ci-dessus est fondamentalement équivalent à:

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