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
}
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.