Is it possible to expand every method of parent interface in child interface?
interface IFoo {
methodOne(a: any)
methodTwo(a: any)
}
interface IBar extends IFoo {
//make IBar have all methods of Ifoo, but make it take additionlal arguments
//as in methodOne(a: any, b: any, c: any)
// and methodTwo(a: any, b: any, c: any)
}
is there a way to achieve this, without repeating all code from IFoo?
You can do this using mapped types and conditional types in typescript 2.8 (unreleased at the time of writing, should be released in March, currently in RC, you can get it via npm install -g typescript@rc)
// Helper
type IsValidArg<T> = T extends object ? keyof T extends never ? false : true : true;
// Works for 3 parameters you can add more as needed, see link below for info
type AddParameters<T> =
T extends (a: infer A, b: infer B, c: infer C) => infer R ? (
IsValidArg<C> extends true ? (a: A, b: B, c: C, addedA: any, addedB: any) => R :
IsValidArg<B> extends true ? (a: A, b: B, addedA: any, addedB: any) => R :
IsValidArg<A> extends true ? (a: A, addedA: any, addedB: any) => R :
(addedA: any, addedB: any) => Promise<R>
) : never;
type InterfaceWithExtraParameters<T> = {
[P in keyof T ] : AddParameters<T[P]>
}
interface IFoo {
methodOne(a: string): string
methodTwo(a: number): number
}
type IBar = InterfaceWithExtraParameters<IFoo>;
// Equivalent to :
// type IBar = {
// methodOne: (a: string, addedA: any, addedB: any) => string;
// methodTwo: (a: number, addedA: any, addedB: any) => number;
// }
// Can be imelmented by a class
class BarImpl implements IBar {
methodOne(a: string, addedA: any, addedB: any): string{
return a;
}
methodTwo(a: number, addedA: any, addedB: any): number {
return a;
}
}
As you can see there is a lot of ceremony to get this done, you might be better off for simple single use cases to just redefine the methods, but it is up to you which route you choose.
To extend AddParameters for more parameters see this answer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With