Alex
Alex

Reputation: 68440

Typescript optional object argument craziness

so I am trying to make a object parameter optional, with optional props, and have a default value at the same time:

const myfunc = ({ stop = false }: { stop?: boolean } = { stop: false }) => {
    // do stuff with "stop"
}

this works fine, but notice that crazy function definition!

Any way to not repeat so much code?

Upvotes: 0

Views: 68

Answers (4)

Rokit
Rokit

Reputation: 1141

If your goal is to have an optional property that is defaulted to something without a crazy-looking function definition, I would simply define the interface and not use destructuring, e.g.:

    interface Options {
      stop?: boolean;
    }
    const myfunc = (options: Options = { stop: false }) => {
      console.log('stop', options.stop);
    }

However, if your actual use-case is an optional boolean, I'd re-examine the design. With boolean, if it's undefined or null, it will evaluate to be falsy anyway.

Upvotes: 1

Keith
Keith

Reputation: 24181

From what I can gather your after where if you don't supply any params, stop = false is default, if you do select some params but leave out stop, stop is also false.

This is how I would do it ->

const myfunc = (p: {stop?: boolean} = { stop: false }) => {
    // do stuff with "stop"
    const {stop = false} = p;
    console.log(stop);
}


myfunc({stop: false});   //stop = false
myfunc({stop: true});    //stop = true
myfunc({});              //stop = false
myfunc();                //stop = false

Adding extra params doesn't get any more complicated either.

const myfunc = (p: {stop?: boolean, start?: boolean} = 
  { stop: false, start: false }) => {
    // do stuff with "stop"
    const {stop = false, start = false} = p;
    console.log(stop, start);
}


myfunc({stop: false});              //false false
myfunc({stop: true, start: true});  //true  true
myfunc({});                         //false false
myfunc();                           //false false 
myfunc({start: true});              //false true

Upvotes: 1

ysfaran
ysfaran

Reputation: 6952

While this question is really opinionated, I see a small logical improvement here, you can set the default value to an empty object:

const myfunc = ({ stop = false }: { stop?: boolean } = {}) => {
    // do stuff with "stop"
}

Anyway I agree that this is not really readable and I used to code like that for quite some time. At some point I realized that it's much more readable if you split this statement:

interface MyFunctionArgs {
  stop?: boolean
}

const myfunc = (myArgs: MyFunctionArgs = {}) => {
    const { stop = false } = myArgs;
    // do stuff with "stop"
}

All in all I would say that TypeScript gives you a lot of ways to implement the same thing, which has its up- and downsides.

Upvotes: 2

CollinD
CollinD

Reputation: 7573

I would probably write this like this:

interface MyFuncOptions {
  stop: boolean;
}
const myFunc = (options: Partial<MyFuncOptions> = {}) => {
  const defaultOptions: MyFuncOptions = {
    stop: false,
  };
  const finalOptions = {
    ...defaultOptions,
    ...options
  }
  const { stop } = finalOptions;
  // ...
}

Upvotes: 3

Related Questions