Home > Blockchain >  Is this a lazy way of avoiding ENUM usage for a parameter?
Is this a lazy way of avoiding ENUM usage for a parameter?

Time:09-16

I'm still learning various coding styles with regard to Typescript and Angular.

Today I came across this with no comments to the method that was coded.

It appears to me that it is somehow enforcing that the value passed in must be one of the defined values but does not make use of ENUM to enforce it which leads to other issues in a large codebase with no documentation.

Am I correct that this is enforcing the value must be equal to one of the || options?

static getEndpoint = (type: string = 'alpha' || 'bravo' || 'charlie) => {}

To me I would have done something along the lines of and ENUM and

export enum MyTypes {
  ALPHA = 'alpha',
  BRAVO = 'bravo',
  CHARLIE = 'charlie',
}

and then

static getEndpoint = (type: MyTypes = MyTypes.ALPHA) => {}

CodePudding user response:

If it were:

static getEndpoint = (type: 'alpha' | 'bravo' | 'charlie' = 'alpha') => {}

then yes. But currently it will accept every string and default to 'alpha'. Because:

(type: string = 'alpha' || 'bravo' || 'charlie')
//     ^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//       |                  \ the default value, 
//       |                    which reduces to: 'alpha'
//       |
//       \-- the actual type (here: string)

Ref: Literal Types

CodePudding user response:

The code shown won't compile, it's missing a '. But assuming you really have this:

static getEndpoint = (type: string = 'alpha' || 'bravo' || 'charlie') => {}

then no, the code isn't enforcing anything except that type must be a string. The code above is functionally equivalent to:

static getEndpoint = (type: string = 'alpha') => {}

The part after the = is a default parameter value, and the expression 'alpha' || 'bravo' || 'charlie' evaluates to 'alpha'.

It was probably meant to be this:

static getEndpoint = (type: 'alpha' | 'bravo' | 'charlie') => {}

That's a union of string literal types. That would require that the type of what was passed for type is the string literal type "alpha", "bravo", or "charlie". This works:

getEndpoint("alpha");

but this doesn't, even if s contains the string "alpha", if that can't be proven at compile-time:

let s: string;
// ...something setting `s`...
getEndpoint(s);

In that form, the union of string literal types performs a similar function to an enum.

To me I would have done something along the lines of...

You've made two changes there:

  • Using an enum
  • Providing a different default value — well, no, it's the same default, but you've done it on purpose :-)

Your version is just fine, but if you wanted to do that with string literal types, it would look like this:

static getEndpoint = (type: 'alpha' | 'bravo' | 'charlie' = 'alpha') => {}
  • Related