Reputation: 3639
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?
Upvotes: 1
Views: 756
Reputation: 249616
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 })
Upvotes: 5