Maintain the specific type based on the provided data, rather than the default value, when a related generic is defined

When it comes to unit tests, I prefer a more flexible approach with dynamic generic types that eliminate the need for type casting.

I want T to be open-ended, but if I specify a type, I expect to receive an exact match.

For R, I need it to precisely match the type of params, regardless of whether T is specified or not.

The issue arises when specifying T and being required to also define R. I have attempted setting its default value to { [key: string]: any }, however, this disrupts the types and fails to accurately reflect the params type.

declare function test<T, R extends { [key: string]: any } = { [key: string]: any }>(
  template: string,
  params: R,
): {t: T, r: R};

// testing without specific generics
const test1 = test('f', {
  a: 'a',
});

test1.t; // expectedly unknown as no specific type was provided
test1.r.a; // expected behavior - recognized as a string
test1.r.b; // expected failure since property does not exist

// testing with a specified generic
const test2 = test<string>('f', {
  a: 'a',
});

test2.t; // expectedly a string
test2.r.a; // failed - treats it as any instead of a string
test2.r.b; // failed - treats it as any instead of forbidding it 

// Attempting another solution
declare function anotherTest<T>(
  template: string,
  params: { [key: string]: any },
): {t: T, r: typeof params}; // aiming for the passed type, not default { [key: string]: any }

It seems challenging to achieve this without separating params into an independent variable and defining its type explicitly. If you have a solution, please share. Thank you in advance!

TS Playground

Answer №1

Unfortunately, the feature is not currently available but the good news is that it is currently in development:

https://github.com/microsoft/TypeScript/issues/10571 https://github.com/microsoft/TypeScript/pull/26349

A potential solution will involve using infer as the key mechanism.

type TypeConstraint = string | boolean;
function getName<A, infer B extends TypeConstraint>(a: A, b: B): B {}

// valid
const abc: boolean = getName<string>("abc", true);
const abc: boolean = getName<string, boolean>("abc", true);

// error
const abc: boolean = getName<string>("abc", 10);

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

Toggle visibility of an Angular 4 component based on the current route

Hello there, I'm facing an issue and not sure if it's possible to resolve. Essentially, I am looking to display a component only when the route matches a certain condition, and hide another component when the route matches a different condition. ...

Using TypeScript to ensure class parameter types without affecting properties

I am tasked with defining a schema for "operations" that will be used in my application. This schema must be easily extendable for other groups of "operations" and should include a dictionary of settings for each keyword. Eventually, a "generic caller" wi ...

Ways to turn off Typescript alerts for return statements

I'm looking to turn off this Typescript warning, as I'm developing scripts that might include return values outside of a function body: https://i.stack.imgur.com/beEyl.png For a better example, check out my github gist The compiled script will ...

Playwright failing to execute GraphQL tests due to TypeScript configuration problems

I'm facing an issue with my repo where I am running tests using Playwright against a graphQL URL. Despite configuring the tests, there is an error indicating that the environment variable defining the environment cannot be found. The repository in qu ...

Guide on exporting Excel data using Angular and TypeScript

My project involves managing a table of information that includes fields for FirstName, LastName, PhoneNumber, Age, and Date. I've created a function that allows me to export the data to an Excel file, but I only want to export specific fields like Fi ...

Exploring the potential of Vue with Router to create a dynamic multi-page

Struggling to come up with a suitable title for this Vue project dilemma. Here's what I'm facing: Recently started using Router in my Vue project and feeling quite lost. The setup in App.vue simply includes <RouterView>, which seems stra ...

Can you explain the significance of <any> when used before a Typescript class constructor parameter?

Currently, I am immersing myself in the Angular - Testing documentation. While going through the section on testing asynchronous services (specifically HTTP services), I came across a class constructor containing an <any> right before the passed argu ...

What is the best way to handle an OR scenario in Playwright?

The Playwright documentation explains that a comma-separated list of CSS selectors will match all elements that can be selected by one of the selectors in that list. However, when I try to implement this, it doesn't seem to work as expected. For exam ...

Tips for including additional properties to a <button> element using ReactJS and Typescript

Currently, I am in the process of creating a unique component which consists of an ordinary <button> tag and has a new prop called aria-current. The issue at hand is that Typescript is flagging an error stating that this property does not exist with ...

The type '0 | Element | undefined' cannot be assigned to the type 'Element'

I encountered the following error: An error occurred when trying to render: Type '0 | Element | undefined' is not assignable to type 'Element'. Type 'undefined' is not assignable to type 'ReactElement<any, any>&apo ...

Converting JSX files to TSX files: a step-by-step guide

I am facing an issue with this particular component on the website. It is currently in .jsx format while the rest of the website uses .tsx files. I need to convert this specific component into a .tsx file. Can someone provide assistance or guidance? Despit ...

Strange occurrences observed while looping through an enum in TypeScript

Just now, I came across this issue while attempting to loop through an enum. Imagine you have the following: enum Gender { Male = 1, Female = 2 } If you write: for (let gender in Gender) { console.log(gender) } You will notice that it iter ...

Methods for adjusting data based on the current user's login

I'm currently working on integrating a user login feature using Angular 6 for a stock management system. The user credentials are saved in the database, and I have successfully retrieved them into a component (login) for validation. After a successful ...

Automatically closing the AppDateTimePicker modal in Vuexy theme after selecting a date

I am currently developing a Vue.js application using the Vuexy theme. One issue I have encountered is with a datetimepicker within a modal. The problem arises when I try to select a date on the datetimepicker component - it closes the modal instead of stay ...

Potentially null object is present in a callback

The code I have is as follows: let ctx = ref.current.getContext("2d"); if(ctx){ ctx.lineWidth=1; // this line executes without errors ctx.strokeStyle=props.barStroke??"darkgray";// this line execut ...

Setting up Material-UI for React in conjunction with Typescript: A step-by-step guide

I've encountered issues while trying to integrate Material UI into my React project that's written in Typescript. Following the tutorial, I began by adding the react-tab-event-plugin. import injectTapEventPlugin from 'react-tap-event-plugi ...

Retrieve the chosen item to automatically fill in the input fields using Ionic 2 and Angular

My goal is to create a dropdown menu populated with a list of items, and when a product is selected, its price should automatically appear in the quantity field. <ion-item> <ion-label>Item</ion-label> <ion-select (ionChange)="getP ...

Is it possible to use TypeScript or Angular to disable or remove arrow key navigation from a PrimeNG Table programmatically?

Is there a way to programmatically prevent left and right arrow key navigation in a PrimeNG Table with cell editing, without the need to modify the Table component source code? You can check out an example here: Angular Primeng Tableedit Demo code. I mana ...

Import statement cannot be used except within a module

I am currently facing an issue with running the production version of my code. I have Node 20.10 and TypeScript 5 installed, but for some reason, I am unable to run the built version. Here are the contents of my package.json and tsconfig.json files: { & ...

Is there a way to make PrismaClient return DateTime fields as Unix timestamps rather than JavaScript date objects?

When utilizing the PrismaClient for database interaction, DateTime fields are returned as JavaScript Date objects instead of Unix timestamp numbers. Despite being stored as Unix timestamp numbers in the database itself, I require the dates to be retrieved ...