I wrote a function
function patchItem = (id: string | number, data: object, params: object = {}, cancelToken?: CancelToken, additionalDispatchData: object = {})
{
}
Here I want to make params
, cancelToken
and additionalDispatchData
parameters optional, but don't want to give cancelToken
an initial value.
The above definition not showing any errors in typescript and compiling perfectly.
Above code is compiling in the following js code
function patchItem = (id, data, params = {}, cancelToken, additionalDispatchData = {})
{
}
But here in JS, the cancelToken
is not optional and I think a mandatory parameter cannot exist in between the two optional parameters as above.
One way I find out is making cancelToken
optional by giving undefined
value as default and remove the question mark.
But I want to know if this is the bug in tsc
, that it should have given undefined
as the default value to cancelToken
in compiled JS or I'm doing some kind of mistake here?
But here in JS, the
cancelToken
is not optional and I think a mandatory parameter cannot exist in between the two optional parameters as above.
In JavaScript, all parameters are optional.
But I want to know if this is the bug in
tsc
, that it should have givenundefined
as the default value tocancelToken
in compiled JS or I'm doing some kind of mistake here?
None of the above. :-) By default, all parameters to a JavaScript function are optional and have a default value of undefined
if no default is provided. The only difference between:
function foo(arg = undefined) { }
and
function foo(arg) { }
is that foo
's arity (the number of parameters it expects) as expressed by foo.length
will be 0
in the first case and 1
in the second case. That's literally the only difference.
It's important to distinguish between JavaScript/TypeScript optional parameters (and TypeScript's function overloading) vs. function overloading as it's handled in other languages like C# or Java. In JavaScript and TypeScript, if you want to allow people to leave off arguments that aren't at the end of the parameter list, you have to handle shuffling the arguments around yourself.
Consider this simpler example:
function foo(a: string, n?: number, o?: object): void
{
console.log(a, n, o);
}
foo("one", 1, {});
foo("two", {}); // Error: Argument of type '{}' is not assignable to parameter of type 'number'.
Notice that you can't just leave off the n
parameter. You have to do this:
foo("two", undefined, {});
If you use TypeScript's function overloading, it will allow you to leave off the middle argument from a type perspective, but your implementation has to handle shuffling the actual received parameter values around:
function foo(a: string, n: number, o: object): void;
function foo(a: string, o: object): void;
function foo(a: string, n?: any, o?: object): void
{
if (typeof n === "object") {
o = n;
n = undefined;
}
console.log(a, n, o);
}
foo("one", 1, {}); // "one", 1, {}
foo("two", {}); // "two", undefined, {}
If you had the overloads but didn't do the shuffling in the implementation, you'd end up with n
referencing an object and o
having undefined
:
// Incorrect
function foo(a: string, n: number, o: object): void;
function foo(a: string, o: object): void;
function foo(a: string, n?: any, o?: object): void
{
console.log(a, n, o);
}
foo("one", 1, {}); // "one", 1, {}
foo("two", {}); // "two", {}, undefined
This all stems from the fact that the static type information doesn't exist at runtime, and there's really only one function.
(It would be possible for TypeScript to output foo("two", undefined, {})
when you write foo("two", {})
in your code and it knows that it only matches the second overload signature, but that's a step beyond what the TypeScript designers are currently willing to have it do. :-) )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.