Reputation: 35973
Given the following signature:
export interface INotificationService {
error(message: string, title?: string, autoHideAfter?: number);
}
How can I call the function error()
not specifying the title
parameter, but setting autoHideAfter
to say 1000
?
Upvotes: 503
Views: 623031
Reputation: 4701
Another approach is:
error(message: string, options?: {title?: string, autoHideAfter?: number});
So when you want to omit the title parameter, just send the data like that:
error('the message', { autoHideAfter: 1 })
I'd rather this options because allows me to add more parameter without having to send the others.
You can also use Partial<T>
type in method's signature but it this case you have to create an interface for your options:
interface IMyOptions {
title: string;
autoHideAfter: number;
}
And then the method's signature can look like:
error(message: string, options?: Partial<IMyOptions>);
Usage is the same as above.
Type Partial<T>
should already be declared in global typings as following:
type Partial<T> = {
[P in keyof T]?: T[P];
};
Upvotes: 69
Reputation: 11565
https://www.typescriptlang.org/docs/handbook/functions.html
In JavaScript, every parameter is optional, and users may leave them off as they see fit. When they do, their value is undefined. We can get this functionality in TypeScript by adding a ? to the end of parameters we want to be optional. For example, let’s say we want the last name parameter from above to be optional:
function buildName(firstName: string, lastName?: string) {
if (lastName) return firstName + " " + lastName;
else return firstName;
}
let result1 = buildName("Bob"); // works correctly now
let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
Expected 1-2 arguments, but got 3.
let result3 = buildName("Bob", "Adams"); // ah, just right
Upvotes: -1
Reputation: 182093
As specified in the documentation, use undefined
:
export interface INotificationService {
error(message: string, title?: string, autoHideAfter? : number);
}
class X {
error(message: string, title?: string, autoHideAfter?: number) {
console.log(message, title, autoHideAfter);
}
}
new X().error("hi there", undefined, 1000);
Upvotes: 545
Reputation: 3243
In such cases you can use "undefined" value for those optional params which you do not want to overwrite
export interface INotificationService {
error(message: string, title?: string, autoHideAfter?: number);
}
You can call error method like
error("it works", undefined, 20);
Be careful null
doesn't work here.
Upvotes: -1
Reputation: 372
In TS you could also make your parameters into an Object and make the value of the object optional, that way you don't have to define every parameters, just the one you want to use.
public functionBeingCalled(obj: {status?: number, error?: string, message?: string}) {
if(obj.message) { console.log(obj.message) }
}
this.functionBeingCalled({message: 'Error Detected'})
Upvotes: 3
Reputation: 1
You could try to set title to null.
This worked for me.
error('This is the ',null,1000)
Upvotes: -3
Reputation: 24474
You can create a helper method that accept a one object parameter base on error arguments
error(message: string, title?: string, autoHideAfter?: number){}
getError(args: { message: string, title?: string, autoHideAfter?: number }) {
return error(args.message, args.title, args.autoHideAfter);
}
Upvotes: 2
Reputation: 106900
You can specify multiple method signatures on the interface then have multiple method overloads on the class method:
interface INotificationService {
error(message: string, title?: string, autoHideAfter?: number);
error(message: string, autoHideAfter: number);
}
class MyNotificationService implements INotificationService {
error(message: string, title?: string, autoHideAfter?: number);
error(message: string, autoHideAfter?: number);
error(message: string, param1?: (string|number), param2?: number) {
var autoHideAfter: number,
title: string;
// example of mapping the parameters
if (param2 != null) {
autoHideAfter = param2;
title = <string> param1;
}
else if (param1 != null) {
if (typeof param1 === "string") {
title = param1;
}
else {
autoHideAfter = param1;
}
}
// use message, autoHideAfter, and title here
}
}
Now all these will work:
var service: INotificationService = new MyNotificationService();
service.error("My message");
service.error("My message", 1000);
service.error("My message", "My title");
service.error("My message", "My title", 1000);
...and the error
method of INotificationService
will have the following options:
Upvotes: 9
Reputation: 25008
you can use optional variable by ?
or if you have multiple optional variable by ...
, example:
function details(name: string, country="CA", address?: string, ...hobbies: string) {
// ...
}
In the above:
name
is requiredcountry
is required and has a default valueaddress
is optionalhobbies
is an array of optional paramsUpvotes: 38
Reputation: 13520
You can do this without an interface.
class myClass{
public error(message: string, title?: string, autoHideAfter? : number){
//....
}
}
use the ?
operator as an optional parameter.
Upvotes: -2
Reputation: 3097
This is almost the same as @Brocco 's answer, but with a slight twist: only pass optional parameters in an object. (And also make params object optional).
It ends up being kind of like Python's **kwargs, but not exactly.
export interface IErrorParams {
title?: string;
autoHideAfter?: number;
}
export interface INotificationService {
// make params optional so you don't have to pass in an empty object
// in the case that you don't want any extra params
error(message: string, params?: IErrorParams);
}
// all of these will work as expected
error('A message with some params but not others:', {autoHideAfter: 42});
error('Another message with some params but not others:', {title: 'StackOverflow'});
error('A message with all params:', {title: 'StackOverflow', autoHideAfter: 42});
error('A message with all params, in a different order:', {autoHideAfter: 42, title: 'StackOverflow'});
error('A message with no params at all:');
Upvotes: 15
Reputation: 65053
Unfortunately there is nothing like this in TypeScript (more details here: https://github.com/Microsoft/TypeScript/issues/467)
But to get around this you can change your params to be an interface:
export interface IErrorParams {
message: string;
title?: string;
autoHideAfter?: number;
}
export interface INotificationService {
error(params: IErrorParams);
}
//then to call it:
error({message: 'msg', autoHideAfter: 42});
Upvotes: 119