1

I have a typescript function, that accepts an options object as a parameter. I have an interface that defines the options. I also have a constant that contains default values for every option. It looks something like this:

interface Options {
  viewportHeight: number
  viewportWidth: number
  // ...
}

const defaults: Options = {
  viewportHeight: 600,
  viewportWidth: 600,
// ...
}

function createGenerator(options: Options) {
  options = { ...defaults, ...options }

  return function generate() {
    // Simplfied
    return {
      value: Math.min(options.viewportWidth, options.viewportHeight),
    }
  }
}

The problem is the following: if I leave all properties of the Options interface requires, then I can't do something like createGenerator({ viewportWidth: 50 }) to set only the options I need and leave the rest by default

If I do make them optional, then all options like options.viewportWidth have the type of number | undefined which causes an error Argument of type 'number | undefined' is not assignable to parameter of type 'number' when I'm trying to use them.

I could define two interfaces like Options and FilledOptions, but that's not DRY. Is there some nice way around it?

1 Answer 1

5

You can use Partial to make all members of a type optional. You will however need to use a different variable for the final parameters, as TS will just take the assigned type and complain that properties may be undefined

interface Options {
  viewportHeight: number
  viewportWidth: number
  // ...
}

const defaults: Options = {
  viewportHeight: 600,
  viewportWidth: 600,
// ...
}

function createGenerator(_options: Partial<Options>) {
  const options = { ...defaults, ..._options }

  return function generate() {
    // Simplfied
    return {
      value: Math.min(options.viewportWidth, options.viewportHeight),
    }
  }
}

createGenerator({ viewportWidth: 50 })

Play

Sign up to request clarification or add additional context in comments.

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.