Home > OS >  How to type an object with optional and default values?
How to type an object with optional and default values?

Time:08-10

I've an old JavaScript (.js) file with a function like so:

export default ({
  guid,
  numItems,
  lastDate,
  filters = [],
  includeCart = true,
  fetchStuff = true,
  withLove = true
}) => () => {
  // do stuff
}

As you can see, the entries in the argument object is getting long so I'd like convert the file to TypeScript (.ts) and put some constraints around this argument object.

I'd want to do something like this:

interface IPayload {
   guid: string
   numItems: number
   lastDate: string
   filters: string[]
   includeCart?: boolean
   fetchStuff?: boolean
   withLove?: boolean
}

export default (payload: IPayload) => () => { // do stuff }

However, since the argument supplies default values into the function, if I create a TypeScript interface, I can't supply default values. So, if the old function had a statement like:

if (includeCart) { // include the cart }

if the property isn't supplied, it would always default to true but in my refactor, it would be undefined thereby changing the behavior of this function.

How would I properly refactor this bit of function in order to make it more kosher in the TypeScript world?

CodePudding user response:

You could list the parameters with default values explicitely and use the spread operator to get the rest of the properties in a seperate variable.

const fn = ({ 
    filters = [], 
    fetchStuff = true, 
    withLove = true, 
    ...payload 
  }: IPayload) => { 
  console.log(filters, fetchStuff, withLove, payload)
}

fn({ guid: "", numItems: 0, lastDate: "", filters: [] })

Playground

CodePudding user response:

You can have a typed argument object with individual properties default values, using destructuring as in the original JS version:

interface IPayload {
  guid: string
  numItems: number
  lastDate: string
  filters: string[] // Should be optional as well BTW?
  includeCart?: boolean
  fetchStuff?: boolean
  withLove?: boolean
}

export default ({
  guid,
  numItems,
  lastDate,
  filters = [],
  includeCart = true
  fetchStuff = true
  withLove = true
}: IPayload) => () => { // do stuff }
  • Related