TypeScript Version: 3.7.0-dev.20190815
Search Terms: void, inference, mixed, unknown, arity, 0-arity, function
Code
export declare function infer<Params, Done, Fail = Error>(
handler?: (params: Params) => any
): (params: Params) => void;
const f = infer(() => {});
f();
Expected behavior:
No errors!
Actual behavior:
Expected 1 arguments, but got 0. ts(2554)
Playground Link: Link
The way you wrote it, the function expects exactly one parameter with type Params. Try this instead:
export declare function infer<Params extends any[], Done, Fail = Error>(
handler?: (...params: Params) => any
): (...params: Params) => void;
const f = infer(() => {});
f(); // works!
@AlCalzone I need always 0 or 1 parameter
It shouldn't infer unknown, but void
declare var f: (params: void) => void
f() // fine
I would argue that I have exactly one parameter of type undefined 😂
@AlCalzone I need always 0 or 1 parameter
The easy way would be using overloads:
export declare function infer<Done, Fail = Error>(handler?: () => any): () => void;
export declare function infer<Param, Done, Fail = Error>(handler?: (param: Param) => any): (params: Param) => void;
const f1 = infer((a: number) => a+1);
f1(1);
const f2 = infer(() => {});
f2();
EDIT: Here's a fancy version with conditional types
export declare function infer<Params extends any[], Done, Fail = Error>(
handler?: (...params: Params) => any
): Params extends [] | [any] // allow 1 or 2 params
? (...params: Params) => void
: ["too many arguments"];
const f1 = infer((a: number) => a+1);
f1(1);
const f0 = infer(() => {});
f0();
const f2 = infer((a, b) => a+b);
f2(1,2); // error here
@AlCalzone this means changing public interface of generics tho, instead of one type I would need to pass tuples, first solution is the same, I already tried it, first generic becomes Done not Params
@AlCalzone
the function expects exactly one parameter with type
If this was true, then it would error early on
const f = infer(() => {}); // error would be here
If this was true, then it would error early on
No. The way you typed it, infer returns a function with exactly one argument of type Params. The error is raised at the call site.
No. The way you typed it, infer returns a function with exactly one argument of type Params. The error is raised at the call site.
This 👆
I don't think it should work like this, why not infer void as parameter type, instead of unknown?
export declare function infer<Params>(
handler?: (params: Params) => void
): (params: Params) => void;
const f = infer(() => {}); // type is (params: unknown) => void
declare var f: (params: void) => void
f() // fine
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
It isn't working as intended :
It isn't working as you intended, but that doesn't mean it makes any sense to anyone else. Sorry.