Skip to content

Fix TypeScript codegen typing for reusable packages#15631

Open
sebastienros wants to merge 4 commits intomainfrom
sebros/fix-ts-codegen-typing
Open

Fix TypeScript codegen typing for reusable packages#15631
sebastienros wants to merge 4 commits intomainfrom
sebros/fix-ts-codegen-typing

Conversation

@sebastienros
Copy link
Copy Markdown
Contributor

@sebastienros sebastienros commented Mar 26, 2026

Description

This fixes the TypeScript codegen regression behind #15507 by keeping the generated public surface structurally typed across independently restored packages.

For main, the fix also renames the public TypeScript interfaces to drop the I prefix and moves the conflict-avoidance naming to the runtime implementation classes instead:

  • public structural types use names like CancellationToken, ReferenceExpression, HandleReference, FooBuilder, and FooBuilderPromise
  • runtime implementation classes use names like CancellationTokenImpl, ReferenceExpressionImpl, FooBuilderImpl, and FooBuilderPromiseImpl
  • callback wrapping and promise-wrapper generation now instantiate the implementation classes consistently
  • main-only generated sample artifacts that should not be tracked (ValidationAppHost/aspire.config.json and .modules/*) are removed from the PR diff

Validation:

  • ./dotnet.sh test tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests.csproj -- --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"
  • npm install --ignore-scripts --no-audit --no-fund, ./dotnet.sh run --project ./src/Aspire.Cli/Aspire.Cli.csproj -- restore --apphost apphost.ts, and npx tsc --noEmit across all 48 playground/polyglot/TypeScript/*/ValidationAppHost samples

Fixes #15507

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No
  • Does the change require an update in our Aspire docs?

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 15631

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 15631"

@sebastienros sebastienros changed the title Fix TypeScript codegen typing for reusable packages [release/13.2] Fix TypeScript codegen typing for reusable packages Mar 26, 2026
@sebastienros
Copy link
Copy Markdown
Contributor Author

The only thing to check mostly is the vode generator class and the base/transport files in the same folder. The other changes are just generated code from samples. These files are all gone in main but still in release/13.2 as they are not a problem. We can do the same change in release/13.2 if we prefer to get rid of them there too.

@sebastienros sebastienros marked this pull request as ready for review March 27, 2026 02:33
Copilot AI review requested due to automatic review settings March 27, 2026 02:33
@sebastienros
Copy link
Copy Markdown
Contributor Author

@DamianEdwards would you mind checking if that implementation solves your problem?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a TypeScript codegen regression (#15507) by shifting generated wrapper typings away from nominal typing across package boundaries and aligning transport behavior for handles/cancellation.

Changes:

  • Updates generated TypeScript transport/base modules to use structural “handle-bearing” inputs, adds cancellation token abstractions, and adds argument marshalling/validation.
  • Adds/refreshes aspire.config.json for multiple polyglot TypeScript ValidationAppHost samples and updates .codegen-hash tracking files.
  • Ensures returned wrapper types remain structural and updates property-object wrapper behavior (via regenerated outputs).

Reviewed changes

Copilot reviewed 73 out of 253 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Storage/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Sql/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Sql/ValidationAppHost/.modules/transport.ts Updates transport: cancellation tokens, argument validation, handle wrapping, connection/auth changes.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Sql/ValidationAppHost/.modules/base.ts Updates base types: structural reference expressions, cancellation token types, transport serialization changes.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Sql/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.SignalR/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.SignalR/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.SignalR/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ServiceBus/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ServiceBus/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ServiceBus/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Search/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Search/ValidationAppHost/.modules/transport.ts Updates transport: cancellation tokens, argument validation, handle wrapping, connection/auth changes.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Search/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Search/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Redis/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Redis/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Redis/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.PostgreSQL/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.PostgreSQL/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.PostgreSQL/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.OperationalInsights/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Kusto/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/transport.ts Updates transport: cancellation tokens, argument validation, handle wrapping, connection/auth changes.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Kusto/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.KeyVault/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Functions/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Functions/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.Functions/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.EventHubs/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CosmosDB/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ContainerRegistry/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.CognitiveServices/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.ApplicationInsights/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppService/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppService/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppService/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppContainers/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/aspire.config.json Adds TypeScript ValidationAppHost configuration and package list.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/.modules/base.ts Regenerates base module with structural reference expressions + cancellation token support.
playground/polyglot/TypeScript/Aspire.Hosting.Azure.AppConfiguration/ValidationAppHost/.modules/.codegen-hash Updates tracked TS codegen output hash.

Copy link
Copy Markdown
Member

@JamesNK JamesNK left a comment

Choose a reason for hiding this comment

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

Reviewed the changes under src/Aspire.Hosting.CodeGeneration.TypeScript and tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests. The structural typing approach for cross-package reuse looks sound.

Three comments inline — the ancestors set mutation in marshalTransportValue is likely a real bug when objects share references in arrays/maps processed via Promise.all.

@github-actions
Copy link
Copy Markdown
Contributor

Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

@github-actions
Copy link
Copy Markdown
Contributor

Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

@github-actions
Copy link
Copy Markdown
Contributor

🎬 CLI E2E Test Recordings — 52 recordings uploaded (commit aae3109)

View recordings
Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunEmptyAppHostProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptEmptyAppHostProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateStartAndStopAspireProject ▶️ View Recording
CreateTypeScriptAppHostWithViteApp ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ▶️ View Recording
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ▶️ View Recording
InitTypeScriptAppHost_AugmentsExistingViteRepoAtRoot ▶️ View Recording
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LegacySettingsMigration_AdjustsRelativeAppHostPath ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RunFromParentDirectory_UsesExistingConfigNearAppHost ▶️ View Recording
RunWithMissingAwaitShowsHelpfulError ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
TypeScriptAppHostWithProjectReferenceIntegration ▶️ View Recording

📹 Recordings uploaded automatically from CI run #23633429036

@davidfowl
Copy link
Copy Markdown
Contributor

So ITypeName is very C#py. What would these interfaces be called if they were normal TS interfaces. Should we let the interfaces be the normal names and the implementations have different names instead of using an I prefix.

@JamesNK
Copy link
Copy Markdown
Member

JamesNK commented Mar 27, 2026

So ITypeName is very C#py. What would these interfaces be called if they were normal TS interfaces. Should we let the interfaces be the normal names and the implementations have different names instead of using an I prefix.

chatgpt says ITypeName was the common standard. It's more common to not prefix with I in modern TypeScript

@sebastienros sebastienros added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Mar 27, 2026
@sebastienros
Copy link
Copy Markdown
Contributor Author

We'll target main instead, not critical for 13.2 and need to change naming

sebastienros and others added 4 commits March 27, 2026 09:53
- generate structural handle-bearing input types for interface-handle parameters
- align generated wrapper property objects with setter capabilities
- update snapshots and regenerate tracked TypeScript validation apphost modules

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@sebastienros sebastienros force-pushed the sebros/fix-ts-codegen-typing branch from aae3109 to c89d8c0 Compare March 27, 2026 17:17
@sebastienros sebastienros changed the title [release/13.2] Fix TypeScript codegen typing for reusable packages Fix TypeScript codegen typing for reusable packages Mar 27, 2026
@sebastienros sebastienros changed the base branch from release/13.2 to main March 27, 2026 17:18
@sebastienros sebastienros enabled auto-merge (squash) March 27, 2026 17:25
@sebastienros sebastienros removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Mar 27, 2026
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.

TypeScript codegen: generated classes with private members prevent reusable npm packages

4 participants