I have a higher-order function, annotate. Its purpose is to assign types to the parameters of the anonymous function it wraps, so that that function does not need its own type annotations. (The shape of { a: number, b: string } is arbitrary and not important here.)
function annotate<
F extends <T extends { a: number; b: string }[]>(...args: [...T]) => any,
>(f: F): F {
return f;
}
(The second "extends" is necessary to get TypeScript to infer the return type rather than assigning it outright.)
However, for some reason, "annotate" only works when the function parameter is a spread tuple:
annotate((...[{ a, b }]) => a);
If we provide the parameter directly, we get the error Target requires 1 element(s) but source may have fewer.
annotate(({ a, b }) => a);
``` (causes a type error)
Why is this happening? How can I make it work with a plain parameter?
The solution I'm looking for should still allow TypeScript to infer the return type:
```typescript
const f = annotate((...[{ a, b }]) => a);
const r = f({ a: 10, b: "abc" }); // typeof r should be "number"
It should should also still accept values that extend the expected type:
const f = annotate((...[{ a, b }]) => {});
f({ a: 10, b: "abc", c: true }); // Should be no error here