Generate a specific mapping for Typescript union to predefined values

In the scenario where I have a type similar to the one below and I aim to associate it with specific values during compile time, I can achieve this by:

type MyType = {
  a: string;
  b: string;
}

const MyMapping: { [k in keyof MyType]: number } = {
  a: 3,
  b: 2,
}

type X = typeof MyMapping['a'] // Output should be 3

Playground Link

Is there a method to apply the same concept to a combination of existing types?

type MyType = {
  a: string;
  b: string;
}

const MyMapping: /* Specialized type here */ = {
  a: 3,
  b: 2,
}

type X = typeof MyMapping['a'] // Expected result is 3

I understand that the approach presented above may not work as-is, but are there alternative formatting techniques to achieve this goal?

Answer №1

To begin with, simplifying {[k in keyof MyType]: number} as

Record<keyof MyType, number>
is a more concise approach, essentially utilizing the predefined mapped type Record.

If you are working with typescript 4.9 or later, leveraging the satisfies operator allows for constraining the variable type while enabling the compiler to deduce the type. When combined with as const to retain the literal types, the desired outcome can be achieved:

const MyMapping = {
  a: 3,
  b: 2,
} as const satisfies Record<keyof MyType, number>

Playground Link

If your TypeScript version is earlier than 4.9, a similar method can be applied using an identity function to facilitate inference while also restricting the type of the object literal:

function makeMap<T extends Record<keyof MyType, V>, V extends number>(o: T & Record<Exclude<keyof T, keyof MyType>, never>) {
  return o
}

const MyMapping = makeMap({
  a: 3,
  b: 2,
  c: 1
})

type X = typeof MyMapping['a'] // 3

https://www.typescriptlang.org/play?ssl=6&ssc=123&pln=6&pc=78#code/C4TwDgpgBAsiAq5oF4oG8CwAoKUCGAXFAM...

The function entails a few key tactics:

  1. The V type parameter forces TypeScript to infer number literals for the values within the object rather than just number
  2. Record<Exclude<keyof T, keyof MyType>, never>
    prevents excess properties, as TypeScript doesn't apply excess property checks when assigning to a type parameter.

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

Issue with ion-select default value not being applied

In my ion-select element, I have multiple options and I want to set a default value based on the CurrentNumber when the view is loaded. Here's the code snippet: <ion-select formControlName="Level"> <ion-option [value]="level.id" *n ...

Using React Native with TypeScript to Select the Parent and Child Checkboxes within a FlatList

My objective is to ensure that when a user selects a checkbox for one of the parent items ('Non Veg Biryanis', 'Pizzas', 'Drinks', 'Desserts') in the flatlist, all corresponding child items should also be selected au ...

When using the `create-react-app` command with the `--typescript` flag, you may encounter an issue when attempting to compile namespaces with the `--

I started a project using npx create-react-app my-app-ts --typescript, then I added two new files, sw-build.js and sw.js in the src/ directory. The content of these files was taken from the discussion on Workbox guidelines at (Guidlines for Using Workbox) ...

Resolving the issue of 'type' property missing but required in 'SeriesXrangeOptions' within the Angular Highcharts module

I'm attempting to showcase a price chart view for a specific cryptocurrency chosen from a list of cryptocurrencies, but I keep encountering a type mismatch error. Within my application, I have utilized the angular-highcharts module and brought in the ...

What is the process of attaching a property to every object within an array using TypeScript?

In my search for adding a property to each object in an array, I came across a solution in AngularJs on Stack Overflow. However, I attempted the following approach which did not yield the desired outcome. Any assistance would be greatly appreciated. ex ...

Are there any solutions to refresh a page by clicking a button in next.js?

I am currently learning how to work with next.js and I'm facing an issue where I need to reload my page to make a new API request. As a beginner, I'm not sure how to achieve this. I've tried a few methods but none of them seem to work. Below ...

Difficulty with Angular's Interpolation and incorporating elements

I've encountered an issue with String Interpolation while following an Angular course. In my server.component.ts file, I've implemented the same code as shown by the teacher in the course: import { Component } from "@angular/core"; @Component ( ...

Is it possible to access NgbdModalContent properties from a different component?

If I have a component with a template containing an Edit button. When the user clicks on it, I want to load another component as a dynamic modal template. The component is named ProfilePictureModalComponent and it includes the Edit button: (Angular code h ...

When trying to reference a vanilla JavaScript file in TypeScript, encountering the issue of the file not being recognized

I have been attempting to import a file into TypeScript that resembles a typical js file intended for use in a script tag. Despite my efforts, I have not found success with various methods. // global.d.ts declare module 'myfile.js' Within the re ...

Using Angular 6 to Format Dates

Can anyone provide instructions on how to achieve the following format in Angular? Expected: 20JAN2019 Currently, with the default Angular pipe, I am getting: 20/01/2019 when using {{slotEndDate | date:'dd/MM/yyyy'}} Do I need to write a ...

Elimination of any null value fields upon form submission in Angular 2

Hey everyone, I'm currently working on a project that uses a Model driven form. When I submit the form, I am encountering an issue where I get null values in my formGroupObj.value. I need to find a way to remove fields with null values. Here is how t ...

TypeScript mandates the inclusion of either one parameter or the other, without the possibility of having neither

Consider the following type: export interface Opts { paths?: string | Array<string>, path?: string | Array<string> } The requirement is that the user must provide either 'paths' or 'path', but it is not mandatory to pa ...

What is the best way to restrict the key of an object type to only be within a specific union in TypeScript?

I need to create a set of server types in a union like this: type Union = 'A' | 'B' | 'C'; After that, I want to define an object type where the keys are limited to only certain options from this Union: // Use only 'A&ap ...

Angular form retains the previous value when saving

I encountered an issue with my form component where it displays previous values instead of updated ones during a save operation. The strange part is that if I close the form and reopen it, the new values are then shown correctly. It seems like the problem ...

Setting `throwIfNamespace=true` in the `.babelrc` file for a `create-react-app` project

Running into a bit of a snag here. I thought setting up a simple app would be smooth sailing, but it seems that's not the case. I created an app using the latest create-react-app and decided to add a <gcse:search> tag. However, I encountered the ...

Specify the correct type for the SVG component when passing it as a prop

Currently, I am in the process of constructing a button component: interface ButtonProps { startIcon?: ... <-- what should be the data type here? } const Button = ({startIcon: StartIcon}) => { return <button>{StartIcon && <Sta ...

What is the process for integrating a tensorflow.js model into a React-based web application?

I've been working on a React web application in Typescript that involves loading a tensorflow.js model and then applying it each time the component updates. While I successfully implemented this in a small demo app without React, I am facing some chal ...

Utilizing Google Sheets as a secure, read-only database for Angular applications without the need to make the sheet accessible to the

Seeking a way to utilize Google Sheets document as a read-only database for my Angular application, I have attempted various methods. However, the challenge with all these approaches is that they necessitate public sharing of the Sheet (accessible to anyon ...

Creating a Blob or ArrayBuffer in Ionic 2 and Cordova: Step-by-Step Guide

Is there a way to generate a blob or an arrayBuffer with TypeScript when using the Camera.getPicture(options) method? I am currently working on an Ionic 2/Cordova project. var options = { quality: 90, destinationType: Camera.DestinationType.FILE_ ...

Printing error stack that includes the source from the source map

I've been trying to take advantage of the native support for source maps in Node, but I'm having trouble getting them to work when printing errors to the console. Despite running node with --enable-source-maps and using the source-map-support pa ...