Home > front end >  How to use optional object members?
How to use optional object members?

Time:11-01

I have an object that always has two members, and in some conditions, a third one can be added.

Attempt #1: optional member

let initObject = {
    headers: headers,
    method: method ? 'GET' : method,
    body?: ''
  }
  if (method === 'POST') {
    initObject.body = body
  }

This fails with TS1162: An object member cannot be declared optional.

Attempt #2: forcibly add a member:

let initObject = {
    headers: headers,
    method: method ? 'GET' : method,
  }
if (method === 'POST') {
    initObject.body = body
  }

This now fails with TS2339: Property 'body' does not exist on type '{ headers: Headers; method: string; }'.

How can I add an optional member to an Object?

I currently use a workaround, but it is repetitive and I am sure there is a nicer way

let initObject
if (method === 'GET') {
    initObject = {
      headers: headers,
      method: 'GET',
    }
  } else if (method === 'POST') {
    initObject = {
      headers: headers,
      method: 'POST',
      body: body
    }
  }

CodePudding user response:

Use an object type respectively an interface (you still need to set the types properly):

Each property in an object type can specify a couple of things: the type, whether the property is optional, and whether the property can be written to.

interface InitObject {
  headers: any;
  method: any; // e.g. 'GET' | 'POST'
  body?: any; // body is optional
}

let initObject: InitObject;

...

if (method === 'GET') {
  initObject = {
    headers: headers,
    method: 'GET'
  };
} else if (method === 'POST') {
  initObject = {
    headers: headers,
    method: 'POST',
    body: body
  };
}

Edit: This also works by using an interface:

let initObject: InitObject = {
  headers: headers,
  method: method ? 'GET' : method
};

if (method === 'POST') { // or maybe initObject.method === 'POST'
  initObject.body = body;
}

CodePudding user response:

I think the answer from @pzaenger is the best solution, but if you don't want to use an interface maybe use:

const initObject = {
    headers,
    method: method || 'GET',
    body: method === 'POST' ? body : undefined
}

Also the ternary condition you're using for method doesn't make sense to me

  • Related