microsoft / microsoft/aspire

TypeScript: `asExisting` returns `Promise<IAzureResource>` instead of the specific resource type, breaking fluent chaining

Open
#17,386 1 comment 0 reactions 0 assignees View on GitHub
area-polyglot triage:bot-seen
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

## Description

In the generated TypeScript AppHost SDK (`aspire.d.ts`), `asExisting` (and likely the related `publishAsExisting` / `runAsExisting` methods) on Azure resource builders are typed to return `Promise` instead of returning the specific resource type they were called on.

This widens the inferred type of any expression that chains these calls, which:

1. Breaks subsequent fluent calls in the chain (because the resulting type no longer has the resource-specific methods such as `withAcrPullIdentity`, `withAzureContainerRegistry`, etc.).
2. Forces docs authors and end users to work around it by splitting the call into two statements:

```typescript
// Doesn't work — acaEnv is inferred as IAzureResource and loses
// withAcrPullIdentity / withAzureContainerRegistry.
const acaEnv = await builder.addAzureContainerAppEnvironment("aca-env")
.asExisting(existingEnvName, { resourceGroup: existingEnvResourceGroup })
.withAcrPullIdentity(pullIdentity);

// Workaround — declare first, then call asExisting on its own line.
const acaEnv = await builder.addAzureContainerAppEnvironment("aca-env");
await acaEnv.asExisting(existingEnvName, { resourceGroup: existingEnvResourceGroup });
await acaEnv.withAcrPullIdentity(pullIdentity);
```

The C# equivalent (`AsExisting`) returns `IResourceBuilder` so the chain stays strongly typed. The TypeScript SDK should do the same.

## Expected behavior

`asExisting` (and `publishAsExisting` / `runAsExisting`) on a typed Azure resource should return a promise of the same resource type (or the resource builder of the same type) so chaining remains type-safe.

For example, on `AzureContainerAppEnvironmentResource`, `asExisting` should be typed roughly as:

```typescript
asExisting(name: ParameterResource, options?: { resourceGroup?: ParameterResource }): Promise;
```

## Repro / context

Encountered while reviewing the docs PR microsoft/aspire.dev#1045 that documents `AsExisting` on `AddAzureContainerAppEnvironment` and the new `WithAcrPullIdentity` API added in #17365. See the review comments on https://github.com/microsoft/aspire.dev/pull/1045#discussion_r3284916426 and https://github.com/microsoft/aspire.dev/pull/1045#discussion_r3284916447 for the original observation.

Affected APIs likely include (at minimum):

- `addAzureContainerAppEnvironment(...).asExisting(...)`
- `addAzureContainerRegistry(...).asExisting(...)`
- `addAzureUserAssignedIdentity(...).asExisting(...)`

…and any other Azure resource builder that exposes `asExisting` / `publishAsExisting` / `runAsExisting`.

## Suggested fix

Update the TypeScript binding generator so the `*AsExisting` family of methods returns the same resource type (`T`) as the receiver instead of the base `IAzureResource`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.