What is the reason that I am able to form an object using string literals, but introducing generics complicates the process?

My goal is to create an Object using string literals.


export type MyCustomType<T extends string> = {
  propertyFromCustomType: T;
};

export type CustomTypeWithLiteral<T extends string> = {
  [P in `${T}_with_literal`]: number;
};

When my creation function does not involve a generic type, everything works smoothly:


const create = (t: MyCustomType<"example">): CustomTypeWithLiteral<"example"> => {
    const prop = `${t.propertyFromCustomType}_with_literal` as const;

    return {
        [prop]: 777
    };
}

However, when the creation function includes a type T itself, it encounters issues:


const create = <T extends string> (t: MyCustomType<T>): CustomTypeWithLiteral<T> => {
    const prop = `${t.propertyFromCustomType}_with_literal` as const;

    return {
        [prop]: 777
    };
} 

Even specifying a specific literal type T does not resolve the problem:


type action = "example"

export type MyCustomType<T extends action> = {
  propertyFromCustomType: T;
};

export type CustomTypeWithLiteral<T extends action> = {
  [P in `${T}_with_literal`]: number;
};


const create = <T extends action> (t: MyCustomType<T>): CustomTypeWithLiteral<T> => {
    const prop = `${t.propertyFromCustomType}_with_literal` as const;

    return {
        [prop]: 777
    };
} 

Try This Code in TypeScript Playground

Answer №1

The reason for this is the unpredictability of the type parameter used when calling the function. Consider the following example:

const propFromMyType: 'example' | 'foo' = 'example';

create2({ propFromMyType })

The expected outcome type would be:

type ResultType = TypeWithGenericLiteral<'example' | 'foo'>
// { example_with_literal: number; foo_with_literal: number; }

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

The error message "Property 'value' is not present on type 'EventTarget & HTMLSelectElement'" indicates that the 'value' property is not recognized on the Event

Here is the code snippet that I am working with: interface IHandleSelection { (value: string): any | void; } interface IPipeChangeEventValueToFunction { (handler: IHandleSelection): (event: React.ChangeEvent<HTMLSelectElement>) => void; ...

Expanding Material UI functionality across various packages within a monorepository

Currently, I am using lerna to develop multiple UI packages. In my project, I am enhancing @material-ui/styles within package a by incorporating additional palette and typography definitions. Although I have successfully integrated the new types in packag ...

Adding extra fields to an existing JSON response in a TypeScript REST API

I am in need of an additional column to be added to my response data. Currently, I am fetching data from multiple REST endpoints one by one and merging the results into a single JSON format to display them in an Angular Mat table. The columns that I want t ...

I'm having trouble retrieving my variable within the socketcluster's socket.on function

How can I store the value of msg in the variable sample when sample is not accessible inside the callback function? import { Injectable } from '@angular/core'; import * as socketCluster from 'socketcluster-client'; @Injectable({ pro ...

Tips on incorporating express-mysql-session in a TypeScript project

I'm experimenting with using express-session and express-mysql-session in a Typescript project. Here's the relevant snippet of my code: import * as express from "express"; import * as expressSession from "express-session"; import * as expressMyS ...

Display or conceal a button in Angular 6 based on certain conditions

In my current project, I am facing a challenge where I need to disable a button while a task is running and then activate it once the task is complete. Specifically, I want a syncing icon to spin when the task status is 'In_progress' and then hid ...

What is the reason behind tsc disregarding the include and exclude options in tsconfig.json?

I am facing an issue with my tsconfig.json file: { "compilerOptions": { "target": "ES6", "lib": [ "DOM", "ES6" ] }, "include": [ "src/server/**/*&q ...

Tips for including a sequelize getter in a model instance?

I'm currently struggling to add a getter to the name field of the Company model object in my project. Despite trying various approaches, I haven't had any success so far. Unfortunately, I also couldn't find a suitable example to guide me thr ...

What is the equivalent of specifying globalDevDependencies for npm @types packages in typings?

I am looking to update a project using tsc@2 and remove typings from my toolchain. Updating common dependencies is easy as they are listed in my typings.json file: "dependencies": { "bluebird": "registry:npm/bluebird#3.3.4+20160515010139", "lodash": ...

What is the best way to import a TypeScript file in index.js?

I've recently developed an application using the react-express-starter template. I have a "server" directory where the backend is created by nodejs, containing an index.js file: const express = require('express'); const app = express(); c ...

Updating an item in the redux state is triggering a never-ending loop, leading to a browser

EXPECTED OUTCOME: My goal is to modify a value in my redux state ISSUE: I am encountering an issue where there is an infinite loop or the browser gets locked down. Despite consulting this Stack Overflow post and the official documentation, I am struggling ...

What is the best approach to managing exceptions consistently across all Angular 2/ Typescript observables?

Throughout the learning process of Angular2, I have noticed that exceptions are often caught right at the point of the call. For example: getHeroes(): Promise<Hero[]> { return this.http.get(this.heroesUrl) .toPromise() ...

How to correctly type the return value of an asynchronous thunk in Redux Toolkit using TypeScript

I am currently working with an async thunk that looks like this: export const updateIndexingConfig = createAsyncThunk( "settings/updateIndexingConfig", (config: UpdateIndexingConfigurationRequest) => { return sdkClient.updateIndexingCo ...

Button for saving content located in expo-router header

I am a beginner in react native and I am attempting to connect a save button in a modal header using expo-router. I have managed to make the button work within the modal itself, but I would like it to be located in the header set by expo-router. It doesn&a ...

What is the best way to filter or choose tuples based on their inclusion in a certain group

I am working with a tuple object that contains nested tuples. const foo = [ { id: 't1', values: ['a', 'b'] }, { id: 't2', values: ['a', 'c'] }, { id: 't3', values: ['b', ...

Tips for integrating and utilizing the MSAL (Microsoft Authentication Library for JavaScript) effectively in a TypeScript-based React single page application

Issue I'm encountering difficulties importing the MSAL library into my TypeScript code. I am using the MSAL for JS library with typings in a basic TypeScript/React project created using create-react-app with react-typescript scripts. As someone who i ...

Tips for configuring VS Code to automatically change a callable property to an arrow function instead of a standard function

When interacting with ts/tsx files in VS Code, the autocompletion feature for callable properties offers two options: propertyName and propertyName(args): https://i.sstatic.net/BFVTm.png However, selecting the second option generates a standard function: ...

Error in typescript: The property 'exact' is not found in the type 'IntrinsicAttributes & RouteProps'

While trying to set up private routing in Typescript, I encountered the following error. Can anyone provide assistance? Type '{ exact: true; render: (routerProps: RouterProps) => Element; }' is not compatible with type 'IntrinsicAttribu ...

Ionic/Angular 2: Issue accessing object in the Page1 class - error caused by: Unable to retrieve the 'name' property as it is undefined

Currently, I am working on developing an application using Ionic and below is the code snippet: <ion-header> <ion-navbar> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> &l ...

Utilize Array in Form Input with Index and Spread Operator

Looking to create a form that can handle array data with dynamic fields in TypeScript. Encountering the following error: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ nam ...