Home > Software design >  Replace conditions with enum in Typescript
Replace conditions with enum in Typescript

Time:12-08

Having the following original code, it is a function which based on the value of toCheck is building a css class:

const computeSomething = (toCheck: string) => {
   return clsx('flex', {
     'flex-start': toCheck === 'FIRST',
     'flex-end': toCheck === 'LAST'
   });
}

The requirement is to use enum for toCheck, tried something but probably it's wrong:

export enum toCheck {
  FIRST = 'FIRST',
  LAST = 'LAST'
}

const computeSomething = (toCheck: string) => {
   return clsx('flex', {
     'flex-start': toCheck.FIRST,
     'flex-end': toCheck.LAST
   });
}

The error says:

Property 'FIRST' does not exist on type 'string'.

Any ideas?

CodePudding user response:

The problem is that your toCheck is not referring to the (intended) enum due to your parameter being named the same (toCheck: string). Changing the name of either should solve the problem:

export enum ToCheckEnum {
  FIRST = 'FIRST',
  LAST = 'LAST'
}

const computeSomething = (toCheck: string) => {
   return clsx('flex', {
     'flex-start': ToCheckEnum.FIRST,
     'flex-end': ToCheckEnum.LAST
   });
}

The convention is that enum/type should have Pascal case so I think this way is better.

CodePudding user response:

Why do you pass in toCheck as an argument? Just do this:

export enum ToCheckEnum {
  FIRST = 'FIRST',
  LAST = 'LAST'
}


const computeSomething = (toCheck: ToCheckEnum) => {
  return clsx('flex', {
    'flex-start': toCheck === ToCheckEnum.FIRST,
    'flex-end': toCheck === ToCheckEnum.LAST
  });
}

CodePudding user response:

You are shadowing the enum by using the same name for your parameter. Use a different name for the enum and the parameter to avoid it. The idiomatic case for enums is PascalCase.

After that, just use a generic that extends the enum type and you should have no problems:

TS Playground link

declare function clsx (...args: unknown[]): void;

enum ToCheck {
  FIRST = 'FIRST',
  LAST = 'LAST',
}

const computeSomething = <T extends typeof ToCheck>(toCheck: T) => {
   return clsx('flex', {
     'flex-start': toCheck.FIRST,
     'flex-end': toCheck.LAST
   });
}

computeSomething(ToCheck); // ok
  • Related