You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Let's say I want to make a decorator. It takes in a function fn and returns one that// 1. Takes an array of fn's first argument, rather than just one// 2. Then takes an extra argument before the rest of fn's parameters// 3. Then takes the rest of fn's parameters as-is.// And let's say we already have a decorator that does 1 & 3, so we just want to insert// that extra argument. Coding it is easy! Typing it is not.//// Though it presents slightly differently, the error seems to stem from tuples getting 'blurred'.// They turn from R into R[number][] or from Parameters<F> into Parameters<F>[number][],// which is similar but makes every parameter type into a union of all of them. // ATTEMPTS THAT DO NOT WORK// Using generic rest argumentfunctionchange1R<T,Rextendsany[]>(fn: (t: T, ...rest: R)=>void){return(ts: T[], ...rest: R)=>fn(ts[0], ...rest);}functionchange1Add2R<T,Rextendsany[]>(fn: (t: T, ...rest: R)=>void){// ERROR: R[number][] is not assignable to type Rreturnchange1R((t: T,x: number, ...rest: R)=>{console.log(x);fn(t, ...rest);});}// Using generic function type for Parametersfunctionchange1F<T,Fextends(...args: any[])=>any>(fn: (t: T, ...rest: Parameters<F>)=>void){return(ts: T[], ...rest: Parameters<F>)=>fn(ts[0], ...rest);}functionchange1Add2F<T,Fextends(...args: any[])=>any>(fn: (t: T, ...rest: Parameters<F>)=>void){// ERROR: Property 0 is missing in type any[] but required in type// [number, ...Parameters<F>[number][]]returnchange1F((t: T,x: number, ...rest: Parameters<F>)=>{console.log(x);fn(t, ...rest);});}// Using both togetherfunctionchange1B<T,Rextendsany[],Fextends(t: T, ...rest: R)=>any>(fn: F,){return(ts: T[], ...rest: R)=>fn(ts[0], ...rest);}functionchange1Add2B<T,Rextendsany[],Fextends(t: T, ...rest: R)=>any>(fn: F,){// ERROR: Property 0 is missing in type any[] but required in type [number, ...R[number][]]returnchange1F((t: T,x: number, ...rest: R)=>{console.log(x);fn(t, ...rest);});}// ONE THAT WORKS// Using complicated type inspectiontypeHead<F>=Fextends(head: infer Head, ...tail: any)=>any ? Head : never;typeTail<F>=Fextends(head: any, ...args: infer Tail)=>any ? Tail : never;functionchange1C<Fextends(...args: any)=>any>(fn: F,){// If you don't explicitly specify the return type here, then it will be inferred as 'any'return(ts: Head<F>[], ...rest: Tail<F>): ReturnType<F>=>fn(ts[0], ...rest);}functionchange1Add2C<Fextends(...args: any)=>any>(fn: F,){// If you don't explicitly specify the return type here, then it will be inferred as 'any'returnchange1C((t: Head<F>,x: number, ...rest: Tail<F>): ReturnType<F>=>{console.log(x);returnfn(t, ...rest);})}
Expected behavior:
The first attempt above (or others) should work. At least, even if there are different errors, the type R[number][] should not appear in any circumstance.
Actual behavior:
The errors encountered are written above. In general, the error seems to stem from tuples getting 'blurred'. They turn from R into R[number][] or from Parameters<F> into Parameters<F>[number][], which are similar but make every parameter type into a union of all of them. Then this type mismatches with the actual parameters type, producing the error.
This is a known design limitation. We'd need the ability represent and reason about tuple types such as [number, ...R] where R is a type parameter R extends any[]. We currently require the rest part of a tuple to be an array type and that's why you're seeing the "blurring" to [number, ...R[number][]]. It would be nice to lift this restriction, but it's not trivial.
TypeScript Version: 3.9.0-dev.20200422
Search Terms:
Rest, variadic, tuple, function, generic
Code
Expected behavior:
The first attempt above (or others) should work. At least, even if there are different errors, the type
R[number][]
should not appear in any circumstance.Actual behavior:
The errors encountered are written above. In general, the error seems to stem from tuples getting 'blurred'. They turn from
R
intoR[number][]
or fromParameters<F>
intoParameters<F>[number][]
, which are similar but make every parameter type into a union of all of them. Then this type mismatches with the actual parameters type, producing the error.Playground Link:
Link to Playground
Related Issues:
Hard to say - possibly #35154 ?
The text was updated successfully, but these errors were encountered: