exactOptionalPropertyTypes: omit a maybe-undefined optional arg via conditional spread; align same-named cross-package types
0a14a9c3-6d45-4b85-a86d-75c10f4de6f0
Under tsconfig exactOptionalPropertyTypes: true, threading an optional parameter (e.g. fn(params: { ctx?: SomeContext })) through a service produced two distinct build errors:
TS2379 "Type 'undefined' is not assignable to type 'SomeContext' with 'exactOptionalPropertyTypes: true'". A caller resolved the value with
await build().catch(() => undefined), givingSomeContext | undefined, then passed it asfn({ ctx }). With exactOptionalPropertyTypes, an optional propertyctx?: Taccepts ABSENCE but NOT an explicitundefinedvalue.TS2375 "Property 'orgIds' is optional in type 'AccessContext' but required in type 'AccessContext'". Two different packages each EXPORTED an interface of the same name (a shared access-context type), differing only in which fields are optional vs required. One caller produced variant A (orgIds optional), the new param was typed as variant B (orgIds required) — exactOptionalPropertyTypes makes them non-assignable even though they look identical.