TypeScript optional object key not behaving as expected

The fetch API does not accept a headers object that has a key with an undefined value. Since each of your optional types can be either string | undefined, the compiler is rejecting them.

Here is an approach that filters the headers to remove those with undefined values. Its type predicate (is) keeps the compiler happy.

const buildHeaders = (requestHeaders: RequestHeaders): HeadersInit =>
    (entry): entry is [string, string] => entry[1] !== undefined

const headers: RequestHeaders = {};

type RequestHeaders = {
  foo?: string; // optional
  bar?: string; // optional
  baz: string; // required!

fetch("Some Data", {
  headers: buildHeaders(headers)

The advantage of this approach is that it lets you limit the keys to a set of predefined strings while also letting you to specify whether each is required or optional.