简体   繁体   中英

How to make some function parameter optional without default value and others with default value?

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 given undefined as the default value to cancelToken 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'.

( on the playground )

Notice that you can't just leave off the n parameter. You have to do this:

foo("two", undefined, {});

( on the playground )

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, {}

( on the playground )

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

( on the playground )

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM