Skip to content

fix(typescript): apply exactOptionalPropertyTypes to inline request types#16978

Open
Swimburger wants to merge 2 commits into
mainfrom
devin/complete-exact-optional-request-types
Open

fix(typescript): apply exactOptionalPropertyTypes to inline request types#16978
Swimburger wants to merge 2 commits into
mainfrom
devin/complete-exact-optional-request-types

Conversation

@Swimburger

@Swimburger Swimburger commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

Supersedes / completes #16972 (whose branch lives on a fork I can't push to). Includes the original commit plus the follow-ups needed to make the change land consistently.

With noSerdeLayer: true, optional properties on inline request types (client/requests/*) are now generated as propName?: Type | undefined, matching what the object type generator already does for type declarations. This satisfies exactOptionalPropertyTypes: true so callers can explicitly set optional fields to undefined.

Changes Made

  • Request wrapper widening (GeneratedRequestWrapperImpl.ts): when a property is optional and the serde layer is off, widen its type node to T | undefined (same !includeSerdeLayer gate the object generator uses). (original fix(typescript): apply exactOptionalPropertyTypes to inline request types #16972 change)
  • Fix double-undefined on optional file uploads (Devin Review finding on fix(typescript): apply exactOptionalPropertyTypes to inline request types #16972): getFileParameterType already appends | undefined for optional files, so the naive widening produced Uploadable | undefined | undefined. Now strip any top-level undefined before re-adding it.
  • Shared stripTopLevelUndefined util: extracted the strip logic (previously private methods in GeneratedObjectTypeImpl) into @fern-typescript/commons/codegen-utils/stripTopLevelUndefined.ts, and refactored both the object type generator and request wrapper generator to use it — so both emission paths handle widening identically.
  • Changelog: moved the hand-edited versions.yml entry into generators/typescript/sdk/changes/unreleased/apply-exact-optional-to-request-types.yml (type: fix); versions.yml reverted to match main (versioning is automation-driven).
  • Regenerated ts-sdk seed outputs to capture the new widening. Example, file-upload/.../OptionalArgsRequest.ts:
    export interface OptionalArgsRequest {
        image_file?: core.file.Uploadable | undefined;   // stays single — no double undefined
    -   request?: unknown;
    +   request?: unknown | undefined;
    }

Testing

  • pnpm turbo run compile --filter @fern-typescript/* — passes
  • biome check on all changed generator sources — passes
  • pnpm seed test --generator ts-sdk --local --skip-scripts — 225/225 fixtures pass
  • Unit tests added/updated — none added (change exercised via seed fixtures)

Link to Devin session: https://app.devin.ai/sessions/a0d61f68646b4af789c322fda6cb4fc4
Requested by: @Swimburger


Open in Devin Review

dg314 and others added 2 commits July 8, 2026 13:04
…ypes

Optional request-wrapper properties now emit `T | undefined` when
`noSerdeLayer: true`, mirroring the object type generator.
…hare stripTopLevelUndefined

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@Swimburger Swimburger self-assigned this Jul 8, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@nitpickybot nitpickybot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR extracts the top-level-undefined-stripping helper into a shared util and applies the exactOptionalPropertyTypes widening to inline request types when the serde layer is off. The core generator change is small, correctly gated, and handles the double-undefined file upload case. The regenerated seed outputs are consistent with the change. No blocking issues found.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-07-08T05:02:29Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
ts-sdk square 129s (n=5) 129s (n=5) 117s -12s (-9.3%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-07-08T05:02:29Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-07-08 21:59 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants