Response type tailored to specific input type

I am working on defining types for a simple function called fun.

Below are the interfaces for the input and response:


interface Input {
  test1?: true
  test2?: true
  test3?: true
}
interface Res {
  test1?: string
  test2?: string
  test3?: string
}

Now, let's take a look at the implementation of the function:


fun(input: Input): Res {
    const res: Res = {}
    if (input.test1) {
      res.test1 = 'jupi'
    }
    if (input.test2) {
      res.test2 = 'jupiX2'
    }
    if (input.test3) {
      res.test3 = 'jupiX3'
    }
    return res
  }

The current types ensure that the response of the function fun will always be of type Res, regardless of the input provided. Additionally, the implementation of fun will return values for each key passed in the input.

One approach to connect input and response types is using Function Overloads.

An example of this approach is shown below:


// Function Overloads for 'fun'
// ...

In this implementation, the RequireMany type is used, where:


type RequireMany<T, Keys extends keyof T = keyof T> = Pick<T, Extract<keyof T, Keys>>

Given that I plan to have at least 7 keys in my input, I am curious to know:

Is there a more efficient or generic way to type the fun function rather than using multiple Function Overloads?

Answer №1

You may consider utilizing generics in the following way:

Typescript Playground Link


type Input = {
  test1?: boolean | undefined
  test2?: boolean | undefined
  test3?: boolean | undefined
}

type Res<T extends Input> = {
  test1: T['test1'] extends boolean ? string : undefined // another option here is to use 'never' instead of 'undefined' depending on your use case
  test2: T['test2'] extends boolean ? string : undefined
  test3: T['test3'] extends boolean ? string : undefined
}

function fun<T extends Input>(input: T): Res<T> {
  return {
    ...('test1' in input ? { test1: 'jupi' } : {}),
    ...('test2' in input ? { test2: 'jupiX2' } : {}),
    ...('test3' in input ? { test3: 'jupiX3' } : {}),
  } as Res<T>
}

console.log(fun({ test1: true }).test1) // hovering over test1 shows that it's resolved to 'string'
console.log(fun({ test1: true }).test2) // test2 is 'undefined'
console.log(fun({ test1: true }).test3) // test3 is 'undefined'

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

Closing Popover Instance from another Component (Ionic, Typescript)

I've been dealing with an issue where a function that I imported from another class isn't getting called and the parser isn't recognizing it. The Popover in my code also can't be closed. I've tried various similar solutions, but no ...

Error: Attempting to access properties of an undefined value while retrieving data from Firebase

Struggling with displaying data in my NextJS app. Data is being fetched from Firebase, and the interface structure is as follows: export default interface IUser { name: string; email: string; uid: string; profileImageURL: string; publicData: { ...

What is the best way to take any constructor type and transform it into a function type that can take the same arguments?

In the code snippet below, a class is created with a constructor that takes an argument of a generic type. This argument determines the type of the parameter received by the second argument. In this case, the first parameter sets the callback function&apos ...

The Angular Cli seems to be having trouble loading a State property and its reducer within the ngrx store all of

Following some minor changes to my application, I encountered an issue with my ngrx store not loading properly. While most of the store properties are displaying as expected and even fetching API results through their reducers, I am noticing that a crucial ...

Develop a user interface that includes the ability to have unspecified properties of an unspecified data type,

interface Sample { value?: string [prop: string]: any } const sampleObject: Sample = { title: 'John' } const data = sampleObject.title By including "any" in the interface, it eliminates the automatically assumed "string" type for the p ...

Configuring global runtime variables in NextJS for server-side operations

Currently, I am utilizing the instrumentation.ts file in NextJS to retrieve configuration dynamically when the server starts up. My goal is to have this configuration accessible during runtime for all API routes and server-side components. What would be th ...

I'm curious about the significance of this in Angular. Can you clarify what type of data this is referring

Can anyone explain the meaning of this specific type declaration? type newtype = (state: EntityState<IEntities>) => IEntities[]; ...

TypeScript does not evaluate the boolean left operand when using the && operator

While working with TypeScript, I encountered a scenario similar to the code snippet below: const getString = (string: string) => string // No errors getString("foo"); // Argument of type 'boolean' is not assignable to parameter of ...

What is the best way to transform a synchronous function call into an observable?

Is there a conventional method or developer in RxJS 6 library that can transform a function call into an observable, as shown below? const liftFun = fun => { try { return of(fun()) } catch (err) { return throwError(err) } ...

Error: unable to access cordova in Ionic 2Another wording for this error message could be:

While running my Ionic app using the command ionic serve -l, I encountered the following error message: Runtime Error Uncaught (in promise): cordova_not_available Stack Error: Uncaught (in promise): cordova_not_available at v (http://localhost:8100/bu ...

Dealing with a Typescript challenge of iterating over a tuple array to extract particular values

I am struggling with writing a function that extracts names from an array of tuples, where each tuple includes a name and an age. My current attempt looks like this: type someTuple = [string, number] function names(namesAndAges: someTuple[]) { let allNa ...

While running tslint in an angular unit test, an error was encountered stating 'unused expression, expected an assignment or function call'

Is there a method to resolve this issue without needing to insert an ignore directive in the file? Error encountered during command execution: ./node_modules/tslint/bin/tslint -p src/tsconfig.json --type-check src/app/app.component.spec.ts [21, 5]: unuse ...

Remove default focus from angular 2 material input field

Currently, I am faced with a dialog containing a text input, radio buttons, and ok cancel buttons. Upon opening the dialog, the cursor automatically blinks inside the text input, causing the placeholder text to zoom out and become difficult to read. The ...

Transform Promise<any> into a designated type failure

Beginner inquiry concerning typescript/angular4+/ionic4. I have a service set up to make backend REST calls, and based on the response received, I need to store that data in local storage for future reference. However, I am encountering a type conversion e ...

In TypeScript, develop a specialized Unwrap<T> utility type

After successfully creating a helper type to unwrap the inner type of an Observable<T>, I began wondering how to make this type completely generic. I wanted it to apply to any type, not just Observable, essentially creating Unwrap<T>. Here is ...

Guide on populating text boxes in a form automatically using ngFor?

As a beginner Angular developer, I am looking to automatically fill in text boxes in a form, specifically 10 text boxes (10 rows) using the ngFor directive. In my research on ngFor examples, I have noticed that most of them focus on populating a list base ...

Guide to inserting an Angular routerLink within a cell in ag-Grid

When attempting to display a link on a basic HTML page, the code looks like this: <a [routerLink]="['/leverance/detail', 13]">A new link</a> However, when trying to render it within an ag-Grid, the approach is as follows: src\ ...

The type 'Readonly<Ref<Readonly<any>>>' does not have the property 'forEach' available

Having an issue with state management in Vue3 (Pinia) using the Composition API. I successfully retrieved an array called countryCodes and now I want to copy all items from this array into another array called countries defined in the state. However, whe ...

How to easily scroll to the top of the previous page in Angular 8

In my Angular 8 application, there are buttons that are meant to take the user back to the previous page when clicked. While the functionality works as expected, I am facing an issue where the page does not automatically scroll to the top upon navigating ...

Adding typing to Firebase Functions handlers V2: A step-by-step guide

Here's a function I am currently working with: export async function onDeleteVideo(event: FirestoreEvent<QueryDocumentSnapshot, { uid: string }>): Promise<any> { if (!event) { return } const { disposables } = event.data.data() ...