0

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?

3
  • 3
    If you have a default option, then it's implicitly not optional.. IOW: just get rid of the ? Commented Nov 15, 2022 at 21:40
  • 2
    Well, really you're dealing with two things here. (1) allowing a params object with no entries, i.e. myfunc({}) and (2) allow no params object, i.e. myfunc(). This leads to the verbosity. Commented Nov 15, 2022 at 21:41
  • You can replace { stop = false } with just { stop } when destructuring to save some space. But if your actual use case is an object with many more properties, I would not destructure and just use something like options.stop. Commented Nov 15, 2022 at 22:03

4 Answers 4

3

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;
  // ...
}
Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

1

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

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.