How to retrieve enums in TypeScript without including them

In TypeScript, to work with a subset of items in an enum, we typically do the following:

enum Operator {
  EQUAL = 'EQUAL',
  NOT_EQUAL = 'NOT_EQUAL',
  LESS = 'LESS',
  GREATER = 'GREATER',
}

type EqualOperators = Exclude<Operator, Operator.LESS | Operator.GREATER>

I'm wondering if there's a way to convert EqualOperators from a type to an enum, so that I can use it directly in a script?

By "use it in a script," I mean being able to access the enum values within a JavaScript function. This is not possible with types. For example:

enum Operator {
  EQUAL = 'EQUAL',
  NOT_EQUAL = 'NOT_EQUAL',
  LESS = 'LESS',
  GREATER = 'GREATER',
}

function getOperator() {
  if (Operator.EQUAL) {
    return "=";
  }
  if (Operator.NOT_EQUAL) {
    return "!=";
  }

  throw new Error('Invalid operator');
}

Any suggestions or solutions would be greatly appreciated. Thank you!

Answer №1

Typescript enums serve as both types and objects. While types and interfaces disappear at runtime, objects remain. This means that in order to use a condition like if (op === Operator.EQUAL), the Operator must exist at runtime because we are utilizing the object aspect of the enum.

In your scenario, the Operators "object" functions similarly to this:

{
  EQUAL: 'EQUAL',         
  NOT_EQUAL: 'NOT_EQUAL', 
  LESS: 'LESS',           
  GREATER: 'GREATER',     
}

If you want to create an object using TypeScript's type system based on the enum, you need to instantiate an object alongside it. One approach is to define a new type called EqualOperators which ensures that each key is assigned the correct value from the original enum.

type EqualOperators = Omit<typeof Operator, 'LESS' | 'GREATER'>;

const EqualOperators: EqualOperators = {
  EQUAL: Operator.EQUAL,
  NOT_EQUAL: Operator.NOT_EQUAL,
}

An alternative method could be to use the Pick utility type instead for defining EqualOperators:

type EqualOperators = Pick<typeof Operator, 'EQUAL' | 'NOT_EQUAL'>;

This approach clearly specifies the "equality" operators, making it easier to maintain when adding new elements. Ultimately, choosing a method depends on how often the original enum changes and what elements are likely to be added in the future.

Answer №2

To achieve this, follow the steps outlined below:

enum Operation {
  ADD = 'ADD',
  SUBTRACT = 'SUBTRACT',
  MULTIPLY = 'MULTIPLY',
  DIVIDE = 'DIVIDE',
}

const BasicOperations = Operation as Omit<typeof Operation, "MULTIPLY" | "DIVIDE">;
type BasicOperations = typeof BasicOperations[keyof typeof BasicOperations];

Answer №3

An enumeration serves as both a data type and a set of fixed values, demonstrated in the code snippet below:

enum Operation {
  ADD = 'ADD',
  SUBTRACT = 'SUBTRACT',
  MULTIPLY = 'MULTIPLY',
  DIVIDE = 'DIVIDE',
}

function getOperation(op: Operation) {
  if (op == Operation.ADD) {
    return "+";
  }
  if (op == Operation.SUBTRACT) {
    return "-";
  }
  if (op == Operation.MULTIPLY) {
    return "*";
  }
  if (op == Operation.DIVIDE){
    return "/";
  }

  throw new Error('invalid operation');
}

console.log(getOperation(Operation.ADD));
console.log(getOperation(Operation.SUBTRACT));
console.log(getOperation(Operation.MULTIPLY));
console.log(getOperation(Operation.DIVIDE));
console.log(getOperation('wrong')); // error
console.log(getOperation('wrong' as any)); // works but will throw an error when running

Playground link

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Typescript Support in Goland IDE for HTML Documents

I'm currently utilizing Go for my programming tasks, and I prefer the Goland IDE developed by Jetbrains. Is there a way for me to incorporate typescript into my .html template files that contain a mix of HTML, CSS, and JS? Your assistance is much ap ...

Difficulty with index.html file in Crypto-JS (Angular 2 app)

After successfully installing crypto-js in my node_modules folder using the command npm install crypto-js, I included the following script in my index.html file so that I could use the CryptoJS.SHA256() method: <html> <head> <script s ...

The error message "SyntaxError: Cannot use import statement outside a module" is encountered when trying to import node-fetch in a Typescript file

I'm facing some challenges with the development of a typescript library npm package. The problem arises when I attempt to import node-fetch for fetch calls. To illustrate my issue, I have set up a sample git repository. These are the commands I used ...

An error has been detected: An unexpected directive was found. Kindly include a @NgModule annotation

I am encountering an issue while trying to import a class into a module in my Ionic/Angular app. Upon attempting to release, the following error message appears: ERROR in : Unexpected directive 'SeedModalPage in /home/robson/Lunes/repositories/bolunes ...

Having trouble with Primeicons not displaying correctly in the tree component

Take a look at my code: https://github.com/d1rtyW0lf/aqp-regroupement Here are the styles I'm using: "styles": [ "node_modules/primeicons/primeicons.css", "node_modules/primeng/resources/primeng.min.css", "node_modules/primeng/resour ...

Using TypeScript to assert the type of a single member in a union of tuples, while letting TypeScript infer the types of the other members

Currently, I am attempting to implement type assertion for the "error-first" pattern. Within my function, it returns tuples in the format of ['error', null] or [null, 'non-error']. The specific condition I want to check for is error = ...

What is the most appropriate form to use, and what factors should be considered in determining

Incorporating generics in typescript allows me to create a generic function in the following manner: Choice 1 declare function foo1<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } Alternatively, I have the option to omit the seco ...

Initializing various objects on the same interface type array in one line

Is there a way to inline initialize an array of the interface type IFooFace in TypeScript with different specific implementations, similar to how it can be done in C#? Or do I have to initialize my objects before the array and then pass them in? In C#, th ...

Error: Issue determining the type of variable. Unable to eliminate type 'any'

I am trying to load some widgets from a template object (possibly JSON in the future). Here's an example: type RectangleTemplate = { name: 'Rectangle'; props: { width: number; height: number; } }; type ButtonTemplate = { nam ...

Export problem in TypeScript

I'm having trouble with exporting in the prisma TypeScript file while executing it within a Node.js GraphQL project. Here is the error I am encountering: 05-12-2018 18:20:16: SyntaxError: /home/user/Publish/PracticeBusiness/src/generated/prisma.ts: ...

Issue with Material UI grid not rendering properly in TypeScript environment

I've been trying to replicate a grid from material-ui using React and Typescript. You can see a live demo here. I modified the example to work with Typescript, so my demo.tsx file looks like this: Code goes here... If you check out the live demo, y ...

Saving a JSON object to multiple JSON objects in TypeScript - The ultimate guide

Currently, I am receiving a JSON object named formDoc containing data from the backend. { "components": [ { "label": "Textfield1", "type": "textfield", "key": "textfield1", ...

"Utilize Typescript for defining the parameter type in this

defineProperties(Element.prototype, { querySelector: { value: querySelectorPatched, writable: true, enumerable: true, configurable: true, }, querySelectorAll: { value(this: HTMLBodyElement): NodeListOf< ...

Incorporating an offset with the I18nPluralPipe

Having trouble with my multiselect dropdown and the text pluralization. I attempted to use the I18nPluralPipe, but can't seem to set an offset of 1. ListItem = [Lion, Tiger, Cat, Fox] Select 1 Item(Tiger) = "Tiger", Select 3 Item(Tiger, Cat, Fox) = ...

Is it possible for the Vanilla JS WebSocket object to accurately assign a protocol value while the "ws" package necessary for Node.js is unable to do so?

I am currently working on creating a WebSocket object in node (version 18.17.0), but I have been facing an issue where setting the protocol using the "ws" library always results in it being an empty string. Surprisingly, the Vanilla JS WebSocket object ca ...

Sending the HTML input value to a Knockout view

Can someone assist me with a dilemma I'm facing? Within CRM on Demand, I have a view that needs to extract values from CRM input fields to conduct a search against CRM via web service. If duplicate records are found, the view should display them. Be ...

What is the reason behind the equality comparison between number[][number] and number in TypeScript?

https://i.stack.imgur.com/htnkb.png type Test = number[][]; // The Test type will be inferred as 'number' based on the image above. Can you explain why number[] is considered an index signature type with a signature of 'number'? ...

How can I add a JavaScript-created element into a Primeng TurboTable component?

I am in the process of replacing a custom-made table with PrimeNG's turbotable. The issue I'm facing is that when I try to insert buttons into the table that call specific JavaScript functions, they end up displaying as [object HTMLInputElement] ...

What is the process of converting TypeScript to JavaScript in Angular 2?

Currently diving into the world of Angular 2 with TypeScript, finding it incredibly intriguing yet also a bit perplexing. The challenge lies in grasping how the code we write in TypeScript translates to ECMAScript when executed. I've come across ment ...

Return true for cucumber datatable in typescript without fail

I am facing an issue where the following step definition always returns true even for incorrect data from the dataTable. Can someone assist me in correcting the syntax in TypeScript with Chai assertions? Then(/^Verify the following details in report$/, a ...