Home > database >  Short and clear syntax for setting property if a value is not undefined?
Short and clear syntax for setting property if a value is not undefined?

Time:05-11

I want to set a property to a value only if the value is not undefined, otherwise I don't want to set the property.

This is how I usually handle this scenario:

  const payload: UpdateDistributionCommandInput = {
    Id: cloudFrontId,
    DistributionConfig: {
      ...distribution.DistributionConfig,
      Aliases: {
        Items: modifiedAliasItems,
        Quantity: modifiedAliasItems.length
      }
    }
  }

  if (typeof distribution.ETag === "string") {
    payload.IfMatch = distribution.ETag;
  }

  const updateDistributionCommand = new UpdateDistributionCommand(payload)

It looks a bit verbose and messy to me. Is there any shorter syntax for this, or other way of approaching this scenario?

CodePudding user response:

You could use the "and" operator.

distribution.ETag && payload.IfMatch = distribution.ETag

You could also use the ternary operator.

paylod.IfMatch = distribution.ETag 
  ? distribution.ETag
  : payload.IfMatch

The nullish coallescing operator (??) would also do.

paylod.IfMatch = distribution.ETag ?? payload.IfMatch

In your example however, you check specifically for a "string" which is different than "not undefined". My solutions will assign as long as the value is not null or undefined. Also, my second and third solutions do in fact always "assign" IfMatch (undefined or a value). If you rely on the property not being assigned, for instance if you use Object.keys(), then this could be an issue.

CodePudding user response:

If payload.ifMatch is defined as ifMatch?: string then the behaviour is dependent on the exactOptionalPropertyTypes compiler option.

Consider:

interface Payload {
  ifMatch?: string
}

With exactOptionalPropertyTypes: false, this will work:

const payload: Payload = {
  ifMatch: undefined
}

as will:

const payload: Payload = {}
payload.ifMatch = undefined

With exactOptionalPropertyTypes: true, you'll get errors:

const payload: Payload = {
  //  ^^^^^^^
  // Type '{ ifMatch: undefined; }' is not assignable to type 'Payload' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
  //  Types of property 'ifMatch' are incompatible.
  //    Type 'undefined' is not assignable to type 'string'.(2375)
  ifMatch: undefined
}

payload.ifMatch = undefined
//^^^^^^^^^^^^^
// Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.(2412)

Playground Link (Toggle exactOptionalPropertyTypes in the TS Config menu)

  • Related