Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does TypeScript require optional parameters after required parameters?

This works:

public console(message: string | undefined, suppressLevel: boolean) {}

But this doesn't:

public console(message?: string, suppressLevel: boolean) {}

Considering the ? seems to basically be a shorthand for | undefined (and when you mouseover in VS Code it says just that), why does TypeScript make a distinction? You could explicitly pass in undefined for an optional parameter and it would be the same as not specifying it at the end.

like image 396
Jez Avatar asked Oct 26 '17 15:10

Jez


People also ask

Why are optional parameter added in TypeScript?

In Typescript, “?” represents optional parameters. We use optional parameters when it's not mandatory for that parameter to have a value or to be specified. Even if a function specifies parameters, you can call it without giving any arguments in JavaScript.

Why are optional parameters added?

Optional Parameters are parameters that can be specified, but are not required. This allows for functions that are more customizable, without requiring parameters that many users will not need.

How do I skip optional parameter TypeScript?

To omit one optional parameter, while providing another in a TypeScript function, pass an undefined value for the optional parameter you want to omit and provide the value for the next, e.g. logArguments(100, undefined, ['a', 'b', 'c']) .

What is optional parameter in TypeScript?

In typescript, the optional parameter is defined as a parameter that can be made optional while passing the values when the function is called and the values that are passed when the function is called is printed with no errors but when the functions have declared the parameters that are ending with “?” are marked as ...

Does TypeScript support optional parameters?

TypeScript provides a Optional parameters feature. By using Optional parameters featuers, we can declare some paramters in the function optional, so that client need not required to pass value to optional parameters.

Why are optional parameters added in TypeScript Mcq?

Developers can use the optional parameter to declare parameters in function optional so that the requirement to pass the value to optional parameters gets eliminated.


2 Answers

Most importantly, this is a javascript fact that is just made more explicit by strongly typing a function signature.

Function parameters are bound positionally in the arguments list. The first passed argument is bound to the first parameter. The second passed argument is bound to the second parameter. And so on. With the optional parameters at the end, a javascript engine knows to bind the end parameters to undefined when the arguments list is too short. However many short the invocation is, that's how many of the end parameters get to be undefined.

If the optional parameters could be in the middle or at the beginning, there wouldn't be enough information at the call site to know which parameters should be bound to which arguments.

function fn(a?: number, b: number) { /* ... */ }

fn(42);

If fn's signature were valid, fn(42) would be ambiguous. Should b be bound to 42 leaving a undefined? Or should a be bound to 42 with b left undefined (and therefore a type error?) In this particular situation, you might want the typescript type checker to ASSUME that there is no error and instead try its hardest to find a valid interpretation of the invocation (the one in which b gets 42) but that would be a more costly overload resolution algorithm and there would still be cases that are ambiguous and the rules would be too complicated to be useful (i.e. fn2(a?: number, b: number, c?: number) { /* ... */ } with fn(42, 3.1415))

Javascript, by having positional arguments with the trailing arguments optional, and with Typescript allowing us to explicitly annotate the signature overloads which are allowed, strike a great balance of expressiveness, reasonability (performance of the type-checker) and bug avoidance.

If overload resolution were more flexible in that way, then it necessarily have to consider more invocations to be valid which might actually be errors. Or it would put the burden on the function body to deal with all the variations completely, such as making all the parameter combinations being union types with eachother and then having to tease those apart in the code, making it harder to read.

like image 115
Jason Kleban Avatar answered Sep 30 '22 02:09

Jason Kleban


public console(message: string | undefined, suppressLevel: boolean) {}

Uses the pipe (|) operator to declare a parameter that is either of type string or undefined. See union types for more detail.

public console(suppressLevel: boolean, message?: string) {}

Declares an optional parameter which as per docs need to follow required parameters.

Any optional parameters must follow required parameters.

So, while in practice, an optional string parameter IS indeed a parameter that is of type string or undefined (or null depending on your settings), those two are different syntax that follow separate rules. Forcing optional parameters to come after required parameters increase readability and functionality, and typescript can not just treat union types as optional since they are two distinctly different things. Hence the difference.

like image 32
Ozan Avatar answered Sep 30 '22 02:09

Ozan