Substitute data types for certain keys within a Typescript interface

Within this code snippet, the goal is to create a new type from an existing one by iterating through the keys and only replacing those that meet a specific condition.

Additionally, union types are being utilized here.

class A {}

class B {
    constructor(public a: A, public n: number, public aa: A[]) {}
}

type X = A | B

type ReplaceKeyTypes<Type extends X, NewKeyType> = {
  [Key in keyof Type]: Key extends X ? NewKeyType : Type[Key]
}

const a: A = new A()
const b: B = new B(a, 1, [a, a])

const c: ReplaceKeyTypes<B, string> = {
    a: 'test',
    n: 2,
    aa: ['xyz']
}

In the final lines of the code above, two errors occur:

  • The assignment of 'number' to 'string' is invalid.
  • The assignment of 'string[]' to 'string' is invalid.

The questions raised include:

  1. Why does c.n switch to a string even though its initial key type is a number, which doesn't fulfill "Key extends X"?
  2. How can changes be applied to keys that are arrays of the union type as well? For instance, how should c.aa shift from X[] to string[] in this scenario?

Answer №1

When using Key in keyof Type, you obtain the literal key, which is the string that identifies the key. It's important to remember to retrieve the value type of the key by using Type[Key]. To handle the array case and correct this oversight, here's the revised solution:

type UpdateKeyTypes<Type extends Y, NewKeyType> = {
  [Key in keyof Type]: Type[Key] extends Y[]
    ? NewKeyType[]
      : Type[Key] extends Y
        ? NewKeyType
        : Type[Key]
}

Answer №2

It may not be suitable for replacing multiple keys at once, but if you only need to update one key, you can do the following:

type UpdatedType = Omit<OriginalType, 'keyToModify'> & {
  keyToModify: NewValueType;
};

I have yet to make this code more generic, but it shouldn't be too difficult to accomplish.

Answer №3

type X = {
  x: string;
  y: string;
  z: string;
};

type Y = Omit<X, "y" | "z">;

type Z = Omit<X, "y" | "z"> & { y: number; z: number };

When you hover over Y, you will see this:

type Y = {
    x: string;
}

And type Z is now defined as:

type Z = {
  x: string;
  y: number; // Updated
  z: number; // Updated
};

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

Retrieving a value in the app component from a map using Angular

I have been struggling to display the values of ValueM, ValueR, and product in my app.component.html file. Can anyone offer a solution or tip to help me move forward? Thank you very much. app.component.ts forkJoin( this.service1.method1(filter1), ...

Discover the unique value in Angular if it is not present in the list

I have a question about handling values in a list and displaying the "create value" component to the user when needed. How can I efficiently compare search input values with those in the list and determine if a match exists? If no match is found, the "cr ...

In Typescript, interfaces are required to have properties written in Pascal Case instead of camel Case

Currently, I am facing a strange issue in my ASP.NET 5 application where I am using Angular 1.4 with TypeScript and RXJS. Somehow, during the runtime, all my interface properties are getting converted from camel casing to Pascal casing. This unexpected beh ...

Implementing Dynamic Updates to a Google Sheets Custom Menu using Typescript

How to Automatically Update a Custom Menu in Google Sheets using Typescript I have successfully set up the following: Dynamically Updating Custom Menu of Google Spreadsheet using Google Apps Script, a demonstration script for dynamically updating the cust ...

What is the process for designing a type that accepts an object and provides an updated version?

Is there a way to create a function that can take an object and return a modified version of that object in this format? const data = { email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e08a8f888ea0848f85ce838f8d"& ...

AngularJS: The 'myInputName' property is not defined and cannot be read

Encountering an error with AngularJS: https://i.sstatic.net/TBHem.png The issue is related to the titleInput TextBox name property: @Html.TextBox("titleInput", null, new { @placeholder = @T("Message title"), @class = "form-control", ng_model = "feed.fee ...

Cease the interval once the array is devoid of elements

I'm currently working on simulating typing effects for incoming server messages by adding an interval to the output. Here's what I have so far: const stream = interval(1000) .pipe( map((): Message => { return messages.pop(); }) ); ...

What is the best way to verify the presence of a value in an SQL column?

I need to check if a value exists in a column. If the value already exists, I do not want to insert it into the table. However, if it does not exist, then I want to add new data. Unfortunately, my attempted solution hasn't been successful. You can fi ...

Error TS2403: All variable declarations following the initial declaration must be of the same type in a React project

While developing my application using Reactjs, I encountered an error upon running it. The error message states: Subsequent variable declarations must have the same type. Variable 'WebGL2RenderingContext' must be of type '{ new (): WebGL2 ...

Enhancing the level of abstraction in selectors within Redux using TypeScript

Here is a custom implementation of using Redux with TypeScript and the connect method. import { connect, ConnectedProps } from 'react-redux' interface RootState { isOn: boolean } const mapState = (state: RootState) =&g ...

NestJS Ensures Type Safety for Mongoose Models, but Model Functions Expecting Incorrect Types (Any)

Shema Interfaces export interface MyCat { name: string; color: string; } export type Cat = MyCat & Document; export const CatSchema = new Schema({ name: { type: String, required: true, }, color: { type: String, required: tr ...

What is the process for creating static pages that can access local data within a NextJS 13 application?

I recently completed a blog tutorial and I must say, it works like a charm. It's able to generate dynamic pages from .md blog posts stored locally, creating a beautiful output. However, I've hit a roadblock while attempting what seems like a sim ...

Angular-template static functions refer to functions that do not require an

Our project utilizes the linting-config provided by AirBnB. There is a rule that stipulates class methods must utilize this or be declared as static. While this rule theoretically makes sense, it seems to present challenges within an angular context. Consi ...

Tips and tricks for displaying JSON data in Angular 2.4.10

In my Angular project, I am facing an issue while trying to display specific JSON data instead of the entire JSON object. Scenario 1 : import { Component, OnInit } from '@angular/core'; import { HttpService } from 'app/http.service'; ...

looking to restrict the interface to only specific types

Currently working with TypeScript and I have a query regarding the utilization of TypeScript interface. Is there a way to selectively extract and output specific key types from the interface being used? While I am able to isolate the type I need, I am inte ...

A guide to teaching TypeScript to automatically determine the type of dynamic new() calls

One of the challenges I'm facing involves dynamically creating subclasses and ensuring that the factory function is aware of the subclass's return type. While I can currently achieve this using a cast, I am exploring options to infer the return ...

React application experiencing freezing when setInterval function is utilized

I've been working on incorporating Conway's Game of Life into a React project, but I'm encountering freezing issues whenever a new generation is triggered. My assumption is that the problem lies in the excessive overhead from constant DOM re ...

Setting a default value for the dropdown in Angular is essential for ensuring a smooth

<select [(ngModel)]="detail.State" (ngModelChange) ="onStateChange()" class="form-control"> <option [ngValue]="null" disabled selected>Select State</option> <option * ...

TypeScript generic types allow you to create reusable components that

function genericIdentity<T>(arg: T): T { return arg; } let myGenericIdentity: <U>(arg: U) => U = genericIdentity; I see that the 'genericIdentity' function is accepting an argument of a generic type. However, I am unsure about ...

Encountering an unexpected termination error when using Typescript, pg, Express, and Psql within a Docker container: "Error: Connection terminated unexpectedly"

I am facing an issue with connecting to my database running on a Docker container using a postgres image: docker run --name postgres-container -p 2345:2345 -e POSTGRES_PASSWORD=password123 -e POSTGRES_USER=admin -d postgres The TypeScript code I have is i ...