-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeScript should infer relationship between function argument types from overloads #57153
Comments
You can do: function Foo(value: number, ok: true): void;
function Foo(value: undefined, ok: false): void;
function Foo(...[value, ok]: [number, true] | [undefined, false]): void { ... } |
That's another workaround, sure, but I have trouble understanding why TypeScript can't infer the case above. Sometimes it feels like trying to make TypeScript work with me instead of against me is a game of cat and mouse. |
It could be (but isn't currently) possible to write function Foo(value: number, ok: true): void;
function Foo(value: undefined, ok: false): void;
function Foo(value,ok) { ... } because the necessary info is already in the overloads, as you say. In fact I recently read an old ts issue saying exactly that - I can't find it right it now though. So that part of your issue is a duplicate. Likewise for type checking the implementation. Here is one way your code could be rewritten to avoid compile errors, yet handle all possibilities safely: // The compiler forces us to type check the `value` in the implementation...
// function Foo(value: number, ok: true): void;
// function Foo(value: undefined, ok: false): void;
function Foo(...[value,ok]: [number,true]|[undefined,false]): void;
function Foo(...[value,ok]: [number,true]|[undefined,false]|[number|undefined,boolean]): void; // | throws "rangeError"
//function Foo(value: number | undefined, ok: boolean): void; // throws "rangeError"
//function Foo(value: number | undefined, ok: boolean): void {
function Foo(...[value,ok]: [number,true]|[undefined,false]|[number|undefined,boolean]): void {
if (ok && typeof value === "number"){
value; // number
}
else if (!ok && typeof value === "undefined"){
value; // number
}
throw "rangeError";
}
// ... you wrote these apparently meaning that Foo might be called with rangeError inputs.
try {
Foo(42, false); // no ERROR:
Foo(undefined, true); // no ERROR:
}
catch(e){}
// ... you wrote these apparently meaning that Foo might be called with rangeError inputs.
declare var value: number | undefined;
declare var ok: boolean;
try {
Foo(value, ok); // no ERROR
} catch (e) {}
// ... you wrote this safe in the knowledge that there is no rangeError inputs so try/catch not needed
declare var args: [number, true] | [undefined, false];
Foo(...args); // no ERROR There is an ambiguity in your code comment "...even though the function overloads guarantee that the above cannot happen:". See #57057 for a proposal to less the verbiage in the final overload. (Additional proposal 2). You will notice that the overloads have been rewritten entirely in |
Duplicate of or strongly related to #13235, #44262, #52478 .
|
This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
π Search Terms
typescript function argument conditional type overloads automatic infer
β Viability Checklist
β Suggestion
It would be nice if compiler could use the overloaded function declarations to automatically infer information about types in the implementation, to avoid unnecessary type checking.
π Motivating Example
https://tsplay.dev/w1LKOW
π» Use Cases
I want to define a function which can receive a union tuple and have an efficient implementation of it.
Unnecessary runtime checking required.
Runtime checking.
The text was updated successfully, but these errors were encountered: