Consider
interface MagicMonkey {
goCrazy(): Magic
goCrazy(): Magic & string
dance(): Magic
dance(): Magic & string
state: "Full" | "Hungry" | "Tired"
}
I want to create a mapped type when applied to the interface above results in something that strictly enforces the below interface
interface MagicMonkey {
goCrazy: Magic & string
dance: Magic & string
}
I've managed to map all the return types by isolating the methods using the trick that was suggested in this question. Like so:
type AnyMethod = (...args: any[]) => any;
type MatchingPropertyKeys<T, U> = ({
[P in keyof T]: T[P] extends U ? P : never
})[keyof T];
type JustMethodKeys<T> = MatchingPropertyKeys<T, AnyMethod>;
type JustMethods<T> = Pick<T, JustMethodKeys<T>>;
type MagicMonkeyMethods = JustMethods<MagicMonkey>
type MagicMonkeyMethodReturnTypes = {
[P in keyof MagicMonkeyMethods]: ReturnType<MagicMonkeyMethods[P]>
}
But it seems to be happy with either implementation of the overloaded methods return types, so the interface below also adheres to the type.
interface MagicMoneyMethods {
goCrazy: Magic & string;
dance: Magic;
}
Which makes sense. But nothing I've tried to apply to filter it seems to work. Because I always end up with a set of keys I can use to Pick
from the original type, which just gets me back to the same place.