Accept any input string upon the instantiation of a class in TypeScript, even without specifying a generic type

Reflect upon the subsequent categorization and forms:

type keyCollection = {
  [key: string]: {
      request: any,
      response: any
  }
}

class customTestClass<TData extends keyCollection = any> {
  testFunction<
    TInput extends keyof TData, 
    TObject = TData extends keyCollection ? TData[TInput]['request'] : any>(input: TInput, data: TObject) {}
}

My intention is that if this class is created without specifying generic parameters, the testFunction should permit any string as its first parameter, and any value as its second parameter. However, when a generic type is provided to the class, it should restrict the values of the testFunction.

Consider the following scenarios:

let x: customTestClass = new customTestClass();
x.testFunction('sample', {}); // functions as intended; no generics specified for the class, hence accepts string as first parameter and anything as second


type sampleGenericKeyCollection = {
  a: {
    'request': string,
    'response': any
  },
  b: {
    'request': string,
    'response': any
  }
}
let y: customTestClass<sampleGenericKeyCollection> = new customTestClass();
y.testFunction("c", 25); // shows correct error; "c" is not a property of the generic
y.testFunction("a", 25); // why no error here? 25 is of type number, not string - also, why no type enforcement in this case?

Comments indicate that instantiation without generics works in the initial test scenario - function accepts any string as its first parameter and any value as its second.

In the second situation, with generics provided during instantiation, testFunction fails to accept "c" as its first parameter because it is not a property of the given generic.

However, in the third test-case, even though the function identifies the key from the input correctly, it allows any type as the second parameter, which I cannot comprehend. The third test-case should allow only a string type as its second parameter.

Why does the functionality differ from my expectations?

Fiddle here

Answer №1

You have opted for the default type (TObject = ...) rather than using a type constraint:

class myTest<TData extends keyCollection = any> {
  testFunction<
    TInput extends keyof TData, 
    TObject extends TData extends keyCollection ? TData[TInput]['request'] : any>(input: TInput, data: TObject) {}
}

Check it out on Playground

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 'posts' binding element is assumed to have a type of 'any' by default

Currently, I'm working on a code project that involves graphql, react, and typescript. In the middle of the process, I encountered an error message stating "Binding element 'posts' implicitly has an 'any' type." I am unsure about w ...

Ways to update the component's state externally

I'm new to Next.js (and React) and I'm attempting to update the state of a component from outside the component. Essentially, I am conditionally rendering HTML in the component and have a button inside the component that triggers a function to se ...

I want to establish the identical response output field name in NestJS by utilizing the @Expose decorator from class-transformer

My Entity definition currently looks like this: export class ItemEntity implements Item { @PrimaryColumn() @IsIn(['product', 'productVariant', 'category']) @IsNotEmpty() itemType: string; @PrimaryColumn() @IsU ...

Creating a unique module using TypeScript in a React application

Having two projects with common functionality has led me to the need for developing my own npm module that utilizes shared code snippets. To achieve this, I created a separate project specifically for housing this shared code (e.g., util). The current set ...

When defining a component decorator in Angular 2, mixing tabs and spaces can lead to an unhandled exception

After refactoring my Angular 2 component code and adding some tabulations, the code suddenly stopped working. Surprisingly, when I removed the tabs (spaces), it started working again. @Component({ templateUrl : './app.component.html', styl ...

Issues with FlexItems not fully occupying available space when using flex wrap

Before presenting my question, here is the relevant code snippet: const App: FC = () => { const [boardWidth, _setBoardWidth] = useState<number>(1400); const [boardHeight, _setBoardHeight] = useState<number>(1000); const [cellWidth, _se ...

What is the purpose of running tsc --build without any project references?

Out of curiosity, I decided to experiment by executing tsc --build on a project without any project references. Surprisingly, the command ran smoothly and completed without any issues. I expected there to be a warning or error since the build flag is typic ...

Tips on organizing eventListener cleanup utilizing event subscription within useEffect?

I am currently using React.useEffect() to add an event listener and remove it on unmount: React.useEffect(() => { const myFn = () => { // do something }; AppState.addEventListener('change', myFn); return () => { ...

Transforming the unmanaged value state of Select into a controlled one by altering the component

I am currently working on creating an edit form to update data from a database based on its ID. Here is the code snippet I have been using: import React, {FormEvent, useEffect, useState} from "react"; import TextField from "@material ...

The parameter 'X' cannot be assigned to the argument of type 'X'

Hello there! I'm diving into Type Script for the first time with VSCode. Encountering these errors: error TS2322: Type '() => string' is not assignable to type 'string'. error TS2322: Type '() => number' is ...

Ensure that only camelCase is permitted in Angular TSLint configurations, while prohibiting the use of Pascal case

In Angular, we are enforcing the use of lower-case first letter Camel case for code. For instance, if a variable is named ProductName with an uppercase first letter, it should trigger a warning or error. Is there a way to configure TSLint to only allow ca ...

Test exceeded the maximum allowable time of 5000 ms in the jest timeout error message

I encountered a timeout error while running a unit test case for a controller. I was mocking the request, response, and next, but jest threw an error during the test run. Can anyone assist me in resolving this issue? employee.controller.ts import { Reque ...

Creating a seamless integration between Angular 2's auth guard and observables to enhance application security

I'm having trouble setting up an auth guard for one of my routes because I am unsure how to implement it with an observable. I am using ngrx/store to store my token. In the guard, I retrieve it using this.store.select('auth'), which returns ...

Having trouble getting Typescript's Pick Array to work properly?

There seems to be an issue when using this line as an array, and I'm unsure how to resolve it: Pick<Author, PickedAuthorFields>[] </questionbody> I'm not sure why there is a problem if i use this line as array and how to fix it: ...

Error received from Http Get request

I am currently facing an issue with my Angular component that is supposed to make a simple HTTP Get request: this.http.get<any>('http://localhost:80/userservice/login', { params: { username: this.model.username, password: this.model.passwo ...

Implement a function for templateURL in AngularJS using Typescript programming language

Here is my current setup: export class MyComponent implements ng.IComponentOptions { public static componentName: string = "myViewer"; public bindings: any; public controller: any; public controllerAs: any; public templateUrl: string; ...

Retrieving the value of an object based on a dynamic key in Typescript

Currently, I am facing an issue with exporting a single value from a configuration object based on the process.env.NODE_ENV variable. Specifically, I am attempting to retrieve the value of the configEnvs variable like this: configEnvs['local']. H ...

TypeScript types for employing Queries within React Query

Currently, I have this setup: // useMyList hook: const allQueries = myList.map((myData) => { return { queryKey: ['myquerykey'], queryFn: myQueryFn } } return useQueries(buildQuery) Within my component, it looks like this: const ...

Angular - pipe function disrupts the flow of execution

Here is the code snippet in question: subscriber.pipe( switchMap(data => { this.getData().pipe( map(() => res), catchError(error => { return of(null); }) ...

Enhance libraries by incorporating type annotations to method arguments in Typescript

Currently, I am utilizing the external library pg-mem, which provides access to LibAdapters. Within this library, there is a method called createTypeormConnection that accepts several arguments of type any. export interface LibAdapters { createTypeormCon ...