microsoft / microsoft/typespec
[Bug]: http-client-js emits unused private contexts for empty clients
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
## Describe the bug
`@typespec/http-client-js` emits private context fields for generated clients that have no operations. Those fields are initialized but never read. A consumer that enables TypeScript `noUnusedLocals` cannot compile the generated client because TypeScript reports `TS6133` for each field.
This is specific to the JavaScript client emitter. It is related to, but distinct from, #8479, which is scoped to the C# client emitter.
## Reproduction
The following public TypeSpec project reproduces the issue:
https://github.com/yoskeoka/ai-arena/tree/f41393621ba220d01a1841e523e11b34c573c938/typespec
From the repository root:
```sh
pnpm --dir typespec install
pnpm --dir typespec run build
pnpm --dir operator-ui install --frozen-lockfile
pnpm --dir operator-ui run build
```
The TypeSpec service emits empty `AiArenaClient` and `SharedClient` classes. The generated
`operator-ui/src/generated/operator-api/src/aiArenaClient.ts` contains equivalent output to:
```ts
export class AiArenaClient {
#context: AiArenaClientContext;
constructor(endpoint: string, options?: AiArenaClientOptions) {
this.#context = createAiArenaClientContext(endpoint, options);
// ... subclients
}
}
export class SharedClient {
#context: SharedClientContext;
constructor(endpoint: string, options?: SharedClientOptions) {
this.#context = createSharedClientContext(endpoint, options);
}
}
```
Neither `#context` field is read. The final command fails with:
```text
src/generated/operator-api/src/aiArenaClient.ts(...): error TS6133: '#context' is declared but its value is never read.
```
The service TypeSpec source and generated-client configuration are at the linked revision. The
consumer enables `noUnusedLocals` in `operator-ui/tsconfig.app.json`.
## Versions
The issue reproduces with the current npm stable release line tested on 2026-09-16:
- `@typespec/compiler`, `@typespec/http`, `@typespec/openapi3`: `1.16.0`
- `@typespec/rest`: `0.86.0`
- `@typespec/http-client-js`: `0.16.2`
- generated runtime: `@typespec/ts-http-runtime`: `0.3.9`
It also reproduces with the project's previous pins (`1.13.0` / `0.83.0` / `0.15.0` / `0.2.1`).
## Expected behavior
The JS emitter should generate strict-TypeScript-safe output for clients with no operations.
For example, it could omit the unused context state and imports, omit empty clients where that is
compatible with the generated API, or otherwise reference the created context. Consumers should
not need to weaken `noUnusedLocals` or permanently hand-edit generated artifacts.
Contributor guide
Research direction
Reproduce the failure with the listed pnpm commands and inspect the generated operator-ui/src/generated/operator-api/src/aiArenaClient.ts alongside operator-ui/tsconfig.app.json. Trace the @typespec/http-client-js emitter entry point that produces empty clients and identify the relevant emitter tests, if present. Done means empty generated clients compile with noUnusedLocals without unused context fields or imports.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100