0

I have a few functions with different argument signatures:

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

I need to create a TypeScript interface (or type) to capture the following:

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

Such that if the method supplied is foo, TypeScript will complain if args is [string], as it should expect [number] for foo. Likewise, if method is bar, args should be of type [string].

So method could be any one of the functions I supply to the interface, and args should be the corresponding arguments for that function.

CaptainStiggz
  • 1,787
  • 6
  • 26
  • 50

1 Answers1

4

You can use generics. Make MyInterface a generic that takes a type argument.

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

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

// Object of shape MyInterface must take a type argument
// That type argument must satisfy 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 errors
}

Typescript playground

If you don't like having to declare type arguments every time you create an object, you can do it up front:

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

const makeAGoodArgument: MyInterfaces = { ... }

You will achieve the same result. It requires a bit more interface and type definitions up front, but once you get to writing your objects, you don't have to supply a type argument with every object you write.

If you were hoping for an interface structure that would infer this for you without a type argument, I would echo this answer: I don't think there's a way (or at least not a clean way) to have the type of one class property to depend on the current value of another property.

Seth Lutske
  • 9,154
  • 5
  • 29
  • 78