Missak Boyajian
Missak Boyajian

Reputation: 2245

Typescript, set default values for optional parameters in class

I have this class

export class dialogConfig {
    title: String;
    message?: String;
    okText?: String;
    withDecline?: false;
    width?: Number;
    height?: Number;
}

and I have this function

  openDialog(config:dialogConfig){
        ...
    });

I wanna call the function like this

  openDialog({
    title: 'viola'
  }

The rest of the parameters that are not specified, I wanna set default values. How can I achieve this.

Upvotes: 4

Views: 13436

Answers (3)

Anton
Anton

Reputation: 940

In my TS file:

interface IDialogConfig {
  title: string;
  message?: string;
  okText?: string;
  withDecline?: boolean;
  width?: number;
  height?: number;
}

But then I create a const and assign some default values in the same file:

export const DialogConfig: IDialogConfig = {
  title: 'My Title',
  message: 'My message",
  okText: "some text",
  withDecline: false,
  width: 24,
  height: 50
}

Then in some other file where I need to use the DialogConfig variable

import { DialogConfig } from './whereever'

console.log(DialogConfig);

but if I need to change a value for some other purpose:

const newDialogConfig = {...DialogConfig};
newDialogConfig.message = "My new message";

console.log(newDialogConfig)

This seems to work pretty well for me.

Upvotes: 0

Kyle Pittman
Kyle Pittman

Reputation: 3097

The less manual object assignment you can do, the better (in my opinion). Let the language built-in features handle this for you.

You can use this function signature for openDialog to achieve what you're looking for:


// note that I have changed this to `interface` here
interface dialogConfig {
    title: String;
    message?: String;
    okText?: String;
    withDecline?: false;
    width?: Number;
    height?: Number;
}

// set your default values for any parameters here, like you see with
// message = 'default'
function openDialog ({ title, message = 'default' }: dialogConfig) {
  console.log(title);
  console.log(message);
}

openDialog({ title: 'Foobar' });
// will output:
// > Foobar
// > default

Upvotes: 4

jcalz
jcalz

Reputation: 330466

Things that should probably change about this question:

  • dialogConfig should be DialogConfig, as it is conventional in TypeScript for named object types to start with an uppercase letter. Initial-lowercase identifiers usually signify variable names or possibly primitive types.

  • I suspect you should be using an interface instead of a class. The value {title: "viola"} is not actually an instance of any such class at runtime. You can use a class as an interface, which is why openDialog({title: "viola"}) is not an error, but it's more straightforward to use an interface directly. Unless you are writing new DialogConfig() or instanceof DialogConfig you don't need class. And if you are writing those things you should be very careful with non-instance literals like {title: "viola"}.

  • Number should be number and String should be string. It's almost always a mistake to use the uppercase versions of primitive data types.

  • false should probably be boolean, unless you're saying that withDecline should, when specified, always be false. That's possible, but I'm confused about how that would work with the intended use case of specifying default values when left out. If you ever want withDecline to be true, then you want boolean.

That gives us this:

interface DialogConfig {
    title: string;
    message?: string;
    okText?: string;
    withDecline?: boolean;
    width?: number;
    height?: number;
}

That being said, here's how I'd assign default values:

const defaultValues = {
    message: "",
    okText: "",
    withDecline: false,
    width: 0,
    height: 0
}

function openDialog(config: DialogConfig) {
    const filledInConfig: Required<DialogConfig> = { ...defaultValues, ...config };    
    console.log(JSON.stringify(filledInConfig));
};

Here I'm using an object called defaultValues, and using object spread to create a new value with all the properties from defaultValues which is then overwritten with all the properties of config. Assuming that config doesn't have any explicitly included undefined properties, this will result in a filledInConfig value of type Required<DialogConfig>, the same as DialogConfig but with all the properties required instead of having some of them as optional.

If you don't want to use object spread there's also Object.assign():

const filledInConfig: Required<DialogConfig> = Object.assign({}, defaultValues, config);

Either way will result in the desired result:

openDialog({
    title: 'viola'
}); 
// {"message":"","okText":"","withDecline":false,"width":0,"height":0,"title":"viola"}

Okay, hope that helps; good luck!

Playground link to code

Upvotes: 13

Related Questions