Guide to assigning object values according to properties/keys

I'm currently diving into Typescript and exploring how to dynamically set object types based on specific keys (using template literals).

Check out the code snippet below:

interface Circle {
  radius: number;
}

interface Square {
  length: number;
}

type TypeName = "circle" | "square"; 
type ObjectType<T> = 
  T extends "circle" ? Circle :
  T extends "square" ? Square :
  never

type Shape = {
    [id: `${TypeName}.${string}`]: ObjectType<TypeName>
}

const circle:Shape = {"circle.anythig": {length: 33}} // Square??
                   //  ^^^^^^ how to force the type based on object property key name?
const square:Shape = {"square.anythig": {length: 33}} // Square 

Playground

Answer №1

To link a specific TypeName with its corresponding ObjectType, you can utilize a mapped type along with key remapping.

type Shape = {
    [ID in TypeName as `${ID}.${string}`]: ObjectType<ID>
}

If there is a discrepancy between the types, this approach will produce the intended error.

const shape: Shape = { 
  "circle.anything": { length: 33 },
                   //  ^^^^^^ Type '{ length: number; }' is not assignable to type 'Circle'
  "square.anything": { length: 33 }
}

Explore this concept further on the Playground

Answer №2

If anyone is curious, here's an alternative approach:


interface Triangle {
  base: number;
  height: number;
}

type Shapes = {
  circle: Circle
  square: Square
  triangle: Triangle
}

type TypeName = "circle" | "square" | "triangle";

type Shape = {
    [ID in keyof Shapes as`${ID}.${string}`]: Shapes[ID]
}

const s:Shape = {"triangle.bar": {base: 10, height: 20}}

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

Angular 4 scatter chart with multiple data points using Google charts

I'm currently developing a scatter graph in Angular 4 using ng2-google-charts from https://www.npmjs.com/package/ng2-google-charts It seems like this is essentially a wrapper for Google Chart Service. The graph looks great with a few values, but whe ...

The use of custom loaders alongside ts-node allows for more flexibility

Is it possible to utilize ts-node with a custom loader? The documentation only mentions enabling esm compatibility. ts-node --esm my-file.ts I am attempting to implement a custom loader for testing an ESM module, but I prefer not to rely on node for compi ...

When using the async pipe with Angular's ngFor, an error message indicates that the argument is

Can you explain why this error message is appearing: Argument of type '[string, { startTime: string; endTime: string; }][] | null' is not assignable to parameter of type 'Collection<unknown>'. It occurs when attempting to utilize ...

Can you provide information on the type signature of the `onChange` event for the MUI DatePicker?

I am utilizing an instance of the MUI DatePicker along with a MomentAdapter: import *, {useState} as React from 'react'; import TextField from '@mui/material/TextField'; import { AdapterMoment } from '@mui/x-date-pickers/AdapterMom ...

Exploring SVG Graphics, Images, and Icons with Nativescript-vue

Can images and icons in SVG format be used, and if so, how can they be implemented? I am currently utilizing NativeScript-Vue 6.0 with TypeScript. ...

What allows us to create an instance of a generic class even without defining the generic type parameter?

It is intriguing how TypeScript allows the instantiation of a generic class without specifying the actual generic type parameter. For instance, in the code snippet below, the class Foo includes a generic type parameter T. However, when creating a new Foo i ...

Using Angular 2 to convert and display data as a particular object type in

I have recently developed a basic application using the Angular2 tutorial as my guide. Initially, I established a straightforward "Book" model: /** * Definition of book model */ export class Book { public data; /** * Constructor for Book ...

Using Typescript and Next.js to handle error messages returned from Axios responses

My Next.js application makes an API call to validate a registration form. The server returns error messages in the following format: {"message":"The given data was invalid.","errors":{"email":["The email has alr ...

Change number-type object fields to string representation

I am in the process of creating a function that takes an object as input and converts all number fields within that object to strings. My goal is for TypeScript to accurately infer the resulting object's fields and types, while also handling nested st ...

Angular Form Validation: Ensuring Data Accuracy

Utilizing angular reactive form to create distance input fields with two boxes labeled as From and To. HTML: <form [formGroup]="form"> <button (click)="addRow()">Add</button> <div formArrayName="distance"> <div *n ...

Modifying the value of a React input component is restricted when the "value" field is utilized

I'm currently utilizing material-UI in my React application. I am facing a challenge where I need to remove the value in an input field by clicking on another component. The issue arises when using the OutlinedInput component with a specified value. ...

Error: The StsConfigLoader provider is not found! MSAL angular

I am currently using Auth0 to manage users in my Angular application, but I want to switch to Azure Identity by utilizing @azure/msal-angular. To make this change, I removed the AuthModule from my app.module and replaced it with MsalModule. However, I enco ...

Typescript - Conditional imports

When working with the moment-timezone module, one issue that arises is receiving a warning if it is included multiple times. In my specific case, I have a module that necessitates the use of this timezone functionality. Since I am unsure whether or not the ...

Unable to retrieve HTTP call response during debugging, although it is visible in the browser

When I send an HTTP request to create a record, I am able to see the added record id in the Network section of browsers like Chrome and Firefox. However, when I try to debug the code and retrieve the same id value, I encounter difficulties. I have tried us ...

Enhance your AJAX calls with jQuery by confidently specifying the data type of successful responses using TypeScript

In our development process, we implement TypeScript for type hinting in our JavaScript code. Type hinting is utilized for Ajax calls as well to define the response data format within the success callback. This exemplifies how it could be structured: inter ...

VS Code is throwing an Error TS7013, while Typescript remains unfazed

In my Typescript/Angular project, I have the following interface: export interface MyInterface { new (helper: MyInterfaceHelpers); } After compiling the project, no errors are shown by the Typescript compiler. However, VSCode highlights it with squiggl ...

Generate a pre-signed URL for an AWS S3 bucket object using Typescript in NextJS, allowing for easy file downloads on the client-side using @aws-sdk/S3Client

In the utilization of v3 of the S3Client, it appears that all existing examples are based on the old aws-sdk package. The goal is for the client (browser) to access a file from S3 without revealing the key from the backend. From my research, it seems tha ...

Developing a versatile table component for integration

My frontend app heavily utilizes tables in its components, so I decided to create a generic component for tables. Initially, I defined a model for each cell within the table: export class MemberTable { public content: string; public type: string; // ...

What is the reason that control flow analysis does not support the never type?

Here is the scenario I'm dealing with (utilizing strictNullChecks): function neverReturns(): never { throw new Error(); } const maybeString: string | null = Math.random() > 0.5 ? "hi" : null; if (!maybeString) { neverReturns(); // th ...

Changes in tabs are discarded when switching between them within Material UI Tabs

I have been experiencing an issue with the Material UI tab component where changes made in tabs are discarded when switching between them. It seems that after switching, the tabs are rendered again from scratch. For example, let's say I have a textFie ...