'Setting a default property value in a type literal in TS

I have the following TS class:

export class TestClass {
   constructor(public options: { a?: number, b?: string, c?: boolean, d?: number }) { }
}

Implementations:

 new TestClass({a:123});
 new TestClass({b:'hello'});

I am looking for a way to set default values for each of the options properties (a, b, c etc.), so that developer can send only part of the parameters, and the other unassigend parameters will get their defaults.

This option is not available:

 constructor(public options: { a?: number = 0, b?: string = '', c?: boolean = false, d?: number = 1 }) { }

because of the "A type literal property cannot have an initializer in TS" restriction.

So the way I implement it now is the following:

 constructor(public options: { a?: number, b?: string, c?: boolean, d?: number }) {
         !options.a && (options.a = 0),
         !options.b && (options.b = ''),
         !options.c && (options.c = false),
         !options.d && (options.d = 1)
}

My problem is that in the real world the options parameter contains many properties, and I don't want to force each property to be written twice, in the constructor signature and in the constructor's body.

My question is if there is a better way to do it.



Solution 1:[1]

Default parameters are used for function/method arguments that are undefined (both for JavaScript and TypeScript), however in your case you have a parameter value with optional properties inside of it. Setting those properties to default values is unfortunately natively not possible.

However, we can slightly improve the syntax of your constructor:

constructor(public options: { a?: number, b?: string, c?: boolean, d?: number }) {
  options.a || options.a = 0;
  options.b || options.b = '';
  options.c || options.c = false;
  options.d || options.d = 1;
}

If you are using ES2020+, you can use logical nullish assignment to make your syntax even cleaner:

constructor(public options: { a?: number, b?: string, c?: boolean, d?: number }) {
  options.a ??= 0;
  options.b ??= '';
  options.c ??= false;
  options.d ??= 1;
}

More info can be found here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1