Search code examples
angulartypescriptenumstyping

How to reference enum types in Typescript?


I'm trying to create Question class that wants different types of answers/responses to a given situation. It might be a DoAnswer (e.g. "run") or a CheckAnswer (e.g. "check the clock"). I created different enums for those because there are only few possible actions and checks in my case and they all only need a reference-able name and a display string, which enum is perfect for. Now I want to somehow store the type of answer the question expects.

I thought of something like answerType: enum; but that doesn't work as you can't have enum as a value type. Java would have something like Class<?> answerType but I can't find a way to do something like this in TS.

The reason I need it is; I want to calculate the correct answer of a given type for a question by doing something like:

this.correctAnswers: DoAnswer[] | CheckAnswer[];

if(answerType is DoAnswer) {
  this.correctAnswers = answerService.calculateCorrectDoAnswers();
  // answerService gets my possibleAnswers and situationInQuestion
}

Maybe I'm just using every concept wrong but I don't see how I could make it better right now.


Solution

  • Enum

    export enum Question {
      DoAnswer = 'run',
      CheckAnswer = 'check the clock'
    };
    

    Type

    export type QuestionType = Question.DoAnswer | Question.CheckAnswer;
    

    Component

    check(answer: QuestionType): void {
        if (answer === 'run') {
          console.log('run')
        }
    
        if (answer === 'check the clock') {
          console.log('clock')
        }
    
        if (answer === 'something else') // ... doesn't compile since you don't have that value defined
      }
    

    UPDATE:

    Probably there is a better way, but you could do it like this:

    Types

    export type DoAnswers =
      | 'run'
      | 'call the police'
      | 'call 911'
      | 'scream for help';
    
    export type CheckAnswers =
      | 'check clock'
      | 'check weapon'
      | 'check location'
      | 'check cars';
    

    Answer utils

    export const answersDo = ['run', 'call the police', 'call 911', 'scream for help'];
    export const answersCheck = [
      'check clock',
      'check weapon',
      'check location',
      'check cars',
    ];
    

    Component

    check(val: DoAnswers | CheckAnswers) {
        if (answersDo.includes(val)) {
          // its a do answer
        }
    
        if (answersCheck.includes(val)) {
          // its a check answer
        }
      }