How can TypeScript leverage types to build values?

I am dealing with the code snippet provided below:

type Chocolate = {
    'flavour': 'Chocolate',
    'calories': 120
}
type Vanilla = {
    'flavour': 'Vanilla',
    'calories': 90
}
type Mango = {
    'flavour': 'Mango',
    'calories': 110
}
type Mint = {
    'flavour': 'Mint',
    'calories': 100
}


type UseCase = Chocolate | Vanilla | Mango | Mint;


export const chocolate: Chocolate = {
    'flavour': 'Chocolate',
    'calories': 120
}
export const vanilla: Vanilla = {
    'flavour': 'Vanilla',
    'calories': 90
}
export const mint: Mint = {
    'flavour': 'Mint',
    'calories': 100
}
export const mango: Mango = {
    'flavour': 'Mango',
    'calories': 110
}

The structure of the code seems quite verbose. Is there a way to efficiently use types as values (or vice versa) since they're essentially similar?

Note that all calorie values are fixed within predefined ranges (i.e., 90/100/110/120), so it's not just a generic number.

Answer №1

If you want to specify string and number literals as literal types, you can utilize a const assertion like this:

export const vanilla = {
    flavour: "Vanilla",
    calories: 90,
} as const;

To determine the type, use the typeof operator:

export type Vanilla = typeof vanilla;

For a more efficient approach, group all flavors in one object and apply as const to that single object:

const flavors = {
    chocolate: {
        flavour: "Chocolate",
        calories: 120,
    },
    vanilla: {
        flavour: "Vanilla",
        calories: 90,
    },
    mint: {
        flavour: "Mint",
        calories: 100,
    },
    mango: {
        flavour: "Mango",
        calories: 110,
    },
} as const;

You can extract the flavor types using typeof:

type Chocolate = typeof flavors.chocolate;
type Vanilla = typeof flavors.vanilla;
type Mango = typeof flavors.mango;
type Mint = typeof flavors.mint;
type UseCase = Chocolate | Vanilla | Mango | Mint;

To access all flavors regardless of key:

type UseCase = typeof flavors[keyof typeof flavors]; // same result as above

To retrieve the initial exports, destructure the flavors object:

export const { chocolate, vanilla, mint, mango } = flavors;

Playground

Answer №2

If you're searching for a solution similar to this

const FlavorList = {
    Strawberry: 100,
    Mint: 80
}

type FlavorType = keyof FlavorList;

type Recipe<T extends FlavorType> = {
    flavor: T,
    calories: FlavorList[T],
}

const prepareRecipe = <T extends FlavorType>(ingredient: Recipe<T>) => {}

prepareRecipe({flavor: 'Strawberry', calories: 100})

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

Warning: An alert has been triggered while generating files using create-react-app

npm WARN <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e896999d9c81849ba8dbccd1ded8d4cfdcd0c59bc6cbca">[email protected]</a> requires a peer of typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= ...

Error message: TypeScript throwing an error stating that the method is undefined while trying to implement

My goal is to create a filter interface in Angular2 using pipes. Here's how I have implemented it: export interface IFilterable{ passesFilter(f : string, isFilter: boolean): boolean; } The implementation of the interface is seen in the following Ser ...

Having trouble establishing a connection with SignalR on my backend, it just doesn't seem to work properly

I am currently working on a project where I am using Vue with TypeScript and @microsoft/signalr. My goal is to create a chat feature using SignalR, and on the backend, I am utilizing C# with ASP.NET Core and docker. Here is the code snippet I have impleme ...

Error: Unable to use import statement outside of a module when deploying Firebase with TypeScript

Every time I try to run firebase deploy, an error pops up while parsing my function triggers. It specifically points to this line of code: import * as functions from 'firebase-functions'; at the beginning of my file. This is a new problem for me ...

Searching for films directed or produced by Michael Bay using Typegoose

I am attempting to retrieve all movies from the getMovies endpoint that were either directed or produced by Michael Bay. async getMovies(user: User): Promise<Movies[]> { return await this.movieModel .find({ $or: [{ director: user.name }, { p ...

Issue 1068: Attribute not found within angular 2 (Ahead of Time Compilation)

I am currently learning Angular 2 and trying to create a "User Register" form. However, I encountered an error stating "Property does not exist on type" during Phone number validation. I am using both JIT and AOT compilers. With the JIT compiler, my user ...

Angular Service singleton constructor being invoked multiple times

I have been facing an issue with using an app-wide service called UserService to store authenticated user details. The problem is that UserService is being instantiated per route rather than shared across routes. To address this, I decided to create a Core ...

How can I clear the cache for GetStaticPaths in NextJs and remove a dynamic route?

This question may seem basic, but I can't seem to find the answer anywhere online. Currently, I am diving into NextJs (using TypeScript) and I have successfully set up a site with dynamic routes, SSR, and incremental regeneration deployed on Vercel. ...

The incorrect initial state is causing issues in the Zustand state management on the Next.js server side

While utilizing zustand as a global state manager, I encountered an issue where the persisted states were not being logged correctly in the server side of nextjs pages. The log would only show the default values (which are null) and not the updated state v ...

I am facing an issue with my useFetch hook causing excessive re-renders

I'm currently working on abstracting my fetch function into a custom hook for my Expo React Native application. The goal is to enable the fetch function to handle POST requests. Initially, I attempted to utilize and modify the useHook() effect availab ...

Typescript: Maximizing efficiency and accuracy

When it comes to developing Angular2 apps using Typescript, what are the essential best practices that we should adhere to? ...

Tips for creating a unit test case for a specialized validator in angular reactive forms

Looking for guidance on creating a test case for this specific method: export class CustomErrorStateMatcher implements ErrorStatematcher { isErrorState(control: FormControl,form:NgForm | FormGroupDirective | null){ return control && control.inval ...

How to use attributes in Angular 2 when initializing a class constructor

Is there a way to transfer attributes from a parent component to the constructor of their child components in Angular 2? The process is halfway solved, with attributes being successfully passed to the view. /client/app.ts import {Component, View, bootst ...

The NodeJS application experiences a crash if incorrect parameters are provided to the API

Currently, I have built a CRUD API using TypeScript with Node.js, Express, and MongoDB. My goal is to ensure that the API functions correctly when the correct parameters are sent through a POST request. However, if incorrect parameters are passed, the Node ...

Ways to incorporate debounce time into an input search field in typescript

Is there a way to incorporate debounce time into a dynamic search box that filters data in a table? I have explored some solutions online, but my code varies slightly as I do not use throttle or similar functions. This is my template code: <input matI ...

NestJS encountered an error while running the test suite: module 'src/article/article.entity' could not be located from 'comment/comment.entity.ts'

I am facing an issue with NestJS and Jest testing. As a newcomer to NestJS, I encountered the "Cannot find module" error when running tests. Specifically, the error message I received while trying to test my service was: src/article/article.service.spec. ...

I'm currently working on building a fresh window with Tauri 1.2, combining the powers of Rust, React, and Typescript. However, I've encountered a few

Utilizing Tauri's WindowBuilder in Rust, I attempted to create a new window. Despite successfully generating a blank window, I encountered challenges: The inability to display any content on the window The failure to close the window Being relativel ...

display angular filter for mat radio option selected from mat-radio group

On the screenshot provided below, there are 2 buttons within a mat radio group. The condition is that if modelForm.get('schedule').value equals '1', then only display the radio button with the value 'A'. Otherwise, show all va ...

Error message "Property 'name' does not exist on type '{}'" is encountered when using Ionic/Angular HttpClient and no data type is specified

While working on my Ionic project, I encountered an error in Angular when trying to fetch data from an API using HttpClient. The error message that popped up was 'Property 'name' does not exist on type '{}'.'. Below is the cod ...

What could be causing the issue: Unable to locate or read the file: ./styles-variables?

I'm currently following a tutorial on how to create responsive layouts with Bootstrap 4 and Angular 6. You can find the tutorial here. I've reached a point where I need to import styles-variables.scss in my styles file, but I keep encountering t ...