I would like to reference one function's parameter types in another function, but only use a subset of them.
//params of bar should be same as foo, except p1 should be a different type
function foo(p1: string, p2: number, p3: boolean){
...
}
//i'd like to do something like this, though it's obviously not valid syntax
function bar(p1: string[], ...rest: Parameters<typeof foo>.slice(1)){
}
Is there a way to do that? Obviously it's not hard to do manually with only 3 parameters, but in my actual code I have more parameters and I'd like to not repeat them.
TypeScript 4.0 +
type DropFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never
function bar(p1: string[], ...rest: DropFirst<Parameters<typeof foo>>) { }
// bar: (p1: string[], p2: number, p3: boolean) => void
Syntax for inferring all tuple elements except the first one now has become simpler. See Robby Cornelissen's answer for versions < 4.0.
type CommonParams = [p2: number, p3: boolean];
function foo2(p1: string, ...rest: CommonParams){}
// foo2: (p1: string, p2: number, p3: boolean) => void
function bar2(p1: string[], ...rest: CommonParams) { }
// bar2: (p1: string[], p2: number, p3: boolean) => void
Named tuples can be used to preserve function parameter names, so there is no lossy conversion.
Playground
You can create a type tuple using the Parameters
utility type, and then create a new type from that, omitting the first type:
type Rest<T extends any[]> =
((...p: T) => void) extends ((p1: infer P1, ...rest: infer R) => void) ? R : never;
function foo(p1: string, p2: number, p3: boolean) {
}
function bar(p1: string[], ...rest: Rest<Parameters<typeof foo>>) {
}
bar([''], 0, true); // ok
bar('', 0, true); // error
bar([''], true, 0); // error
See also 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