A TypeScript interface that corresponds to a function and its input parameters

I have multiple functions with various argument types:

function foo(a: number) {...}
function bar(a: string) {...}
...

To tackle this, I want to define a TypeScript interface (or type) that can handle these scenarios:

interface MyInterface {
   method: typeof foo | typeof bar;
   args: Parameters<foo | bar>;
}

The goal is to ensure that if the method provided is foo, TypeScript will raise an error if args is passed as [string], since it should actually expect [number]. Similarly, if method is bar, then args must be of type [string].

Ultimately, method could represent any of the functions specified in the interface, with args corresponding to the arguments required for that particular function.

Answer №1

To utilize generics, modify MyInterface to be a generic that accepts a type argument.

// Creating a generic interface that needs a type argument
interface MyInterface<T> {
  method: (arg: T) => void,
  args: T
}

// Implementing your functions
const foo = (thing: string) => { console.log(thing) }
const bar = (thing: number) => { console.log(thing) }

// An object that fulfills the requirements of MyInterface needs a type argument
// The type argument must match the function foo:
const makeAGoodArgument: MyInterface<string> = {
  method: foo,
  args: 'whatever'
}

const makeAnotherGoodArgument: MyInterface<number> = {
  method: bar,
  args: 80
}

const makeABadArgument: MyInterface<string> = {
  method: foo,
  args: 800 // <---- this causes an error
}

Typescript playground

If you find it cumbersome to specify type arguments every time you create an object, you can set it up in advance:

type MyInterfaces = MyInterface<string> | MyInterface<number>

const makeAGoodArgument: MyInterfaces = { ... }

You will achieve the same outcome. While it may require more upfront interface and type declarations, once you start writing your objects, you won't need to provide a type argument for each one.

If you were looking for an interface structure that could infer this without a type argument, I would refer back to this answer: There might not be a way (or at least not a straightforward way) to have the type of one class property rely on another property's current value.

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

Assign a dynamic class to an element within an ngFor iteration

I am working with a template that includes an app-subscriber component being iterated over using *ngFor: <app-subscriber *ngFor="let stream of streams" [stream]="stream" [session]="session" (speakEvents)='onSpeakEvent($event)'> ...

Make sure to include `jquery` in the types section of your tsconfig file

I've encountered an issue while trying to use jQuery in my Angular-TypeScript project. After installing jquery using "npm install @type/jquery", I am receiving the following error when trying to serve: Error TS2592: Cannot find name '$'. Is ...

Step-by-step guide on deploying Angular Universal

Exploring Angular universal and working on understanding deployment strategies. Check out the Github repository at https://github.com/angular/universal-starter This project includes Angular 2 Universal, TypeScript 2, and Webpack 2. After running the comm ...

Is OnPush Change Detection failing to detect state changes?

Curious about the issue with the OnPush change detection strategy not functioning properly in this demonstration. My understanding is that OnPush change detection should activate when a property reference changes. To ensure this, a new array must be set e ...

The mongoose fails to establish a connection with the Mongo Db Atlas

I am having issues with my simple node express app when trying to connect to MongoDB atlas. Despite deleting node_modules and re-downloading all packages, I am still encountering the same error. The specific error message reads as follows: Cannot read pro ...

TypeScript purity - "The variable exports is not defined"

I encountered an issue with my simple client-server TypeScript application where every import statement in my client.ts file triggers a ReferenceError: exports is not defined error in the browser after loading the HTML. Here is the project structure: root ...

Setting up the TypeScript compiler locally in the package.json file

UPDATE #1: It appears that I have managed to come up with a functional configuration, but I am open to any suggestions for improvement. Feel free to check out the answer here: THE ORIGINAL INQUIRY: I am in the process of setting up my environment so that ...

Executing vitest on compiled javascript files

Currently facing issues running vitest on compiled JavaScript. Numerous errors are appearing, such as: TypeError: Cannot read properties of undefined (reading 'spyOn') TypeError: Cannot read properties of undefined (reading 'mock') and ...

What sets apart an inlined return type from a return type defined in a separate type definition within a function?

I'm experiencing inconsistent behavior when I specify the return type of a function inline compared to defining it in a separate type definition. For instance: interface Foo { bar: string; } type Fooer = () => Foo; const foo1: Fooer = () =& ...

"Encountered a TypeError while attempting to send a server action to a custom

My custom form component, <ClientForm>, is built using Radix Primitives. "use client"; import { FC } from "react"; import * as Form from "@radix-ui/react-form"; const ClientForm: FC = (props) => ( <Form.Root {.. ...

Can a function cast an object automatically if it meets certain conditions?

Imagine having an object that has the potential to belong to one of two different classes in a given scenario: const obj: Class1 | Class2 = ... if ( checkIfClass1(obj) ) { // obj = <Class1> obj ... } else { // obj = <Class2> ...

Incorporating typings for bootstrap-table while compiling TypeScript in an ASP.NET Core application

In my ASP.NET Core 5 app, I have chosen to use TypeScript instead of JavaScript. As part of this decision, I am utilizing some JavaScript libraries in my project and need type definitions for them to compile smoothly. To facilitate this process, I have co ...

Step-by-step guide on developing a fresh zod schema while automatically determining its type

Is there a way to reassign the value of an object using TypeScript? I have an interface defined as follows: interface Root { userId: number; id: number; title: string; completed: boolean; } I am familiar with creating a zod schema from th ...

"Exploring the best practice: Defining types in React with Typescript before or after

As a newcomer to typescript, I have noticed that some projects declare the type before the component while others declare it after the component. Can someone explain the differences between these approaches? export type TProps = { item: string; } expor ...

Getting the Angular component class reference within a triggered Highcharts selection event callback - what's the best approach?

It seems like I'm facing a common javascript closure issue, but let me illustrate it with a specific example as I'm struggling to grasp it in an Angular context. In my Angular component, I'm using the Highcharts library to visualize data. W ...

Having trouble with Nextjs API Integration - encountering error 404

I'm currently facing a major issue and I've hit a dead end. I've been spending days trying to connect my local nextjs 14 app to the CVENT API, but I keep receiving a persistent 404 error. Here's what is displayed in the frontend console ...

A class or another interface is the only type that an interface is allowed to extend

We are currently using typescript version 2.9.2 I encountered an issue while trying to extend the interface DropDownOption. I received the error "error TS2312: An interface may only extend a class or another interface." Is there an alternate approach to ...

Managing the outcome of numerous asynchronous calls before accessing the database post-result collection

Hey everyone, I'm just getting started with node.js and I'm working on the following tasks: Calling the AWS API to create Cognito users by passing data. After all requests are completed, inserting all the records into the database. In my code, ...

Adding connected types to a list using Typescript

Question regarding Typescript fundamentals. In my code, I have a list that combines two types using the & operator. Here is how it's initialized: let objects: (Object & number)[] = []; I'm unsure how to add values to this list. I attem ...

The function screen.getByText is not available in this context

My experience with jest and react-testing-library has been smooth for the most part, but I encountered some challenges when transitioning to the screen > getByText/etc testing method. Test describe('test the dashboard when loaded', () => { ...