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.

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.