Why does TypeScript require a generic type parameter when arguments have already been provided?

When I attempted to use the argument p to infer type P, TypeScript still prompted me to provide type P. Why is that?

const numberStringConverter = <T extends string | number,P extends {x: any}>(p: P): T => {
  if(typeof p.x === 'string'){
    return Number(p.x) as T
  }
  if(typeof p.x === 'number'){
    return String(p.x) as T
  }
  return p.x as T;
}
const ret = numberStringConverter<string>({x:1}) // Expected 2 type arguments, but got 1.

I encountered a similar issue on https://github.com/Microsoft/TypeScript/issues/10571, although I am uncertain about it.

This example is simplified, and there may be alternative ways to approach this problem.

Answer №1

P extends {x: any} in this scenario, you are indicating to accept any extended object of type {x:any}

You should specify One and Two classes for reporting purposes

interface Base {x:any}

interface One extends Base {
  y?:string
}

interface Two extends Base {
  z?:string
}


const numberStringConverter = <T extends string | number,P extends Base >(p: P): T => {
  if(typeof p.x === 'string'){
    return Number(p.x) as T
  }
  if(typeof p.x === 'number'){
    return String(p.x) as T
  }
  return p.x as T;
}


 numberStringConverter<string,One>({x:1});
 numberStringConverter<string,Two>({x:1});

If only one class is accepted, avoid using extends and directly pass the class as a parameter

const numberStringConverter2 = <T extends string | number,>(p: Base): T => {
      if(typeof p.x === 'string'){
        return Number(p.x) as T
      }
      if(typeof p.x === 'number'){
        return String(p.x) as T
      }
      return p.x as T;
    }

You can also utilize it differently. If Generic does not have a specified type, it defaults to any.

    const numberStringConverter = <T extends string | number,P extends {x: any}=any>(p: P): T => {
      if(typeof p.x === 'string'){
        return Number(p.x) as T
      }
      if(typeof p.x === 'number'){
        return String(p.x) as T
      }
      return p.x as T;
    }
    
    
     numberStringConverter<string>({x:1});
     numberStringConverter<string>({x:1});
    
    
    // The issue with this approach is that the ts compiler won't flag an error here 
//and the p.x line in the function will cause an error at runtime
    // has to be identified during runtime
     numberStringConverter<string>(5);

However, I believe this method suits your requirements best.

interface Base { x:any}

const numberStringConverter = <T extends string | number,P extends Base =Base>(p: P): T => {
  if(typeof p.x === 'string'){
    return Number(p.x) as T
  }
  if(typeof p.x === 'number'){
    return String(p.x) as T
  }
  return p.x as T;
}


 numberStringConverter<string>({x:1});
 numberStringConverter<string>({x:1});

 // ts compiler will show error
 numberStringConverter<string>(5);

P extends Base =Base where you define that this type is the default unless a specific generic type is provided.

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

How can you type a collection of initialized class instances in Typescript when given an object containing classes?

Imagine having an object that resembles the following: const typeMap = {category1: Category1, category2: Category2} In this case, Category1 and Category2 refer to classes, and there could potentially be hundreds of different categories. Now I also have a ...

Is there a way to help my KafkaJS consumer stay patient while waiting for a broker to become available?

My KafkaJS consumer setup looks like this: // Create the kafka client const kafka = new Kafka({ clientId, brokers, }); // Create the consumer const consumer = this.kafka.consumer({ groupId, heartbeatInterval: 3000, sessionTimeout: 30000, }); // ...

In TypeScript, deduce the optional generic type automatically

Feeling a bit out of my depth here. I need to perform an inference on a generic that includes an optional "parse" function which returns the formatted value [or throws]. They say code speaks louder than words, so let's take a look at the example: exp ...

Using Typescript to incorporate Next.js on Firebase Functions

I'm currently working on deploying a Next.js application to Firebase Functions. import next from 'next' import {https} from 'firebase-functions' const server = next({ dev: process.env.NODE_ENV !== 'production', conf: ...

Why does the page not work when I enter a certain URL with an ID parameter, and instead displays the error message "Uncaught ReferenceError: System is not defined"?

This is my "app.routing.ts": import {provideRouter, RouterConfig} from "@angular/router"; import {DashboardComponent} from "./dashboard.component"; import {HeroesComponent} from "./heroes.component"; import {HeroDetailsComponent} from "./hero-details.com ...

Setting up tsconfig.json to enable support for either string literals or string templates involves adjusting the compiler options

After utilizing swagger codgen with the typescript-aurelia template to create API code, I noticed that a significant amount of string literals were being used in the resulting code. Despite encountering errors when running the transpiler tsc from the comma ...

Best practices for safely handling dynamic keys in Typescript

I am searching for a secure method to create keyed objects in this manner: interface Types { RED: 'RED'; BLUE: 'BLUE'; GREEN: 'GREEN'; } type TypeKeys = keyof Types; const COLORS: Types = { RED: 'RED', B ...

Guide on setting up global typing for AngularJS in your project

I have been working on a project that initially used the deprecated typings method for incorporating Typescript definitions. I now want to transition to using the @types method instead. Currently, we have a typings.json file located in the root of the pro ...

Tips for accessing a specific ListItem within the Menu Component using MUI for React

Within my code, I am working with a List that contains multiple ListItems pulled from an array called myCollection. Each ListItem has a MenuIcon element which triggers a menu to appear, providing the option to delete the specific item. Here is a simplified ...

What could be causing the error message (No overload matches this call) to pop up when attempting to subscribe to .valueChanges() in order to retrieve data from Firestore?

Currently, I am developing an Angular application that utilizes Firebase Firestore database through the angularfire2 library. However, I am encountering a challenge. I must admit that my background is more in Java than TypeScript, so there might be some g ...

Modifying the value of a property in an object array created using the map method is ineffective

I have a collection of objects: https://i.sstatic.net/XNrcU.png Within the collection, I wished to include an additional property to the objects. To achieve this, I utilized the map function: returnArray = returnArray.map((obj) => { obj.active = "fal ...

Azure pipeline failing to run Visual Studio 2017 task because of outdated Typescript SDK version

The Visual Studio 2017 build encounters an error during the build process src\Service\node_modules\utility-types\dist\aliases-and-guards.d.ts(10,51): Error TS2304: Build:Cannot find name 'bigint This issue is specific to the ...

Tips for getting Angular's HttpClient to return an object rather than a string?

How can I make HttpClient return the data in JSON Object format? The Angular documentation states that HttpClient should automatically parse returned JSON data as an object. However, in my project, it only returns the data as a string. Although using JSO ...

Possibility for Automatic Type Inference in Generics

Is there a way to have a method infer the type of function parameter without specifying its generic? Currently it is 'GET' | 'POST', but I only need the literal 'GET' const func = <Params, Method extends "GET" | & ...

Tips for retaining the value of a variable when the page is reloaded

I need to store the value of the variable loggedIn, as it determines the behavior of a function in appComponent.html. Can you explain how I can achieve this? Template of app component: <li class="nav-item"> <a class ...

Looking for a Webpack setup for a React Components Library that includes Typescript, SASS, CSS Modules, and SASS support

I'm on the lookout for a functional Webpack configuration tailored for a React Components Library that includes TypeScript, SASS, and CSS Modules with SASS support. If anyone has one they'd like to share, I would be extremely grateful! ...

Leverage the JSON Web Token module within a Chrome extension

Currently in the process of developing a chrome extension but encountering an issue with loading the json web token node module in my Node.js setup. background-script.ts import jwt from 'jsonwebtoken'; // import * as jwt from '../node_mod ...

Tips for sending data in Angular 8's Http GET method within a service class, especially when the backend requires a dictionary format

I am working on a C# backend with an HttpGet method that is expecting a dictionary as request parameters. public async Task<IActionResult> Search([BindRequired, FromQuery] IDictionary<string, object> pairs) Currently, my frontend is built in A ...

Limit the frequency of function calls in Typescript

Update: After some research, I've learned that throttle has the capability to drop excess function invocations, making it unsuitable for my needs. I am still seeking an idiomatic solution to process every item in a queue at an appropriate pace without ...

Unable to utilize the namespace 'RouteComponentProps' as a specified type

When using TypeScript to define an interface that extends RouteComponentProp, I encountered some issues: VSCode error: [ts] Cannot use namespace "RouteComponentProps" as a type. Console error: Cannot use namespace 'RouteComponentProps' as a typ ...