feat(compiler): add experimental $provideTypeInfo provider and program.getTypeInfo API - #11489
Conversation
… API Add a new experimental `$onInfo` library hook (gated behind the `type-info-hook` compiler feature flag) and `program.getTypeInfo(type)` API allowing libraries to contribute extra, domain-specific info about types for IDE hover and tooling. Wire it into LSP hover and add a `@typespec/http` provider surfacing verb + URI template + response status codes.
commit: |
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
The `type-info-hook` feature is now checked against the package that declares the $onInfo hook rather than the consuming project. Libraries opt in via their own tspconfig.yaml and consumers see the info without enabling anything. Enable it in @typespec/http and ship library tspconfig.yaml in bundles so it works in the playground.
- Report a dedicated `on-info-fail` diagnostic when an `$onInfo` provider crashes during a design-time build, instead of reusing the misleading `on-validate-fail` code. - Use vitest `expect` in the new info hook tests. - Badge the "Providing info" docs page as experimental in the sidebar.
The `type-info-hook` opt-in is resolved from the declaring package's own config, but `tspconfig.yaml` was missing from `package.json#files`, so the hook was silently dropped for anyone installing @typespec/http from a registry. It only ever worked inside the monorepo. Other review feedback: - `getTypeInfo` no longer reports diagnostics after compilation finished; it traces instead, so a crashing provider cannot accumulate duplicates on a cached Program or flip `continueToNextStage`. Drops the now unused `on-info-fail` diagnostic. - Fix the `defineInfoHook` JSDoc example, which returned an array and did not type check against `OnInfoHook`. - Add an end-to-end test exercising the real registration path, plus coverage for the status code range and `*` branches. - Fix a broken link to the configuration docs and document that a library must ship its `tspconfig.yaml`.
`$on*` in this codebase means "compilation lifecycle phase callback" — `$onValidate` and `$onEmit` both run as part of the compile pipeline. This extension point is defined by the opposite property: it never runs during compilation and must not mutate the type graph. `$onInfo` imported exactly the connotation the docs had to disclaim, and "on info" isn't an event the way "on validate" is. The implementation already spoke the right language internally (`registerInfoProvider`, `InfoProvider`, "a library provides this"). Naming it after the data it produces also lines it up with the query side: `TypeInfo` (type), `$provideTypeInfo` (provider), `program.getTypeInfo` (query). $onInfo -> $provideTypeInfo OnInfoHook -> TypeInfoProvider InfoContext -> TypeInfoContext defineInfoHook -> defineTypeInfoProvider registerInfoProvider -> registerTypeInfoProvider type-info-hook -> type-info-provider (compiler feature) Also drops the remaining "hook" framing from the docs and comments. The feature is experimental and gated, so nothing depends on the old names yet.
There was a problem hiding this comment.
Pull request overview
Adds a new experimental “type info” contribution mechanism so TypeSpec libraries can lazily provide extra domain-specific markdown (e.g., HTTP route details) for IDE hover/tooling via a new program.getTypeInfo(type) API, gated behind a per-library compiler feature opt-in.
Changes:
- Introduces
$provideTypeInfodiscovery/registration in the compiler (feature-gated), plusProgram.getTypeInfoto query merged provider output. - Extends the language server hover details to append contributed info (with a horizontal rule separator) and adds comprehensive compiler/server tests.
- Implements an
@typespec/httpprovider that surfaces resolved HTTP route + response status codes, adds docs, and ensures bundling/publishing preserves per-librarytspconfig.yamlfeature opt-ins.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| website/src/content/docs/docs/extending-typespec/providing-type-info.md | New documentation for authoring and consuming $provideTypeInfo contributions. |
| website/src/content/current-sidebar.ts | Adds the new doc page to the sidebar with an “experimental” badge. |
| packages/http/tspconfig.yaml | Opts @typespec/http into the type-info-provider feature for provider registration. |
| packages/http/test/type-info.test.ts | Tests HTTP provider output and verifies real compiler registration via program.getTypeInfo. |
| packages/http/src/type-info.ts | Implements $provideTypeInfo for HTTP operations (route + response status codes). |
| packages/http/src/tsp-index.ts | Exports $provideTypeInfo from the library entry point. |
| packages/http/package.json | Ensures tspconfig.yaml is shipped so the per-library opt-in survives publishing. |
| packages/compiler/test/type-info-provider.test.ts | Compiler-level tests for merging, gating, and error handling of providers. |
| packages/compiler/test/server/get-hover.test.ts | Language-server hover tests verifying appended info and separator behavior. |
| packages/compiler/test/server/completion.tspconfig.test.ts | Updates config completion to include type-info-provider and its description. |
| packages/compiler/test/core/cli/actions/info.test.ts | Updates tsp info feature listing output to include type-info-provider. |
| packages/compiler/src/server/type-details.ts | Appends contributed type info to symbol details/hover output. |
| packages/compiler/src/index.ts | Exports defineTypeInfoProvider and related TypeInfo* types from public API surface. |
| packages/compiler/src/core/types.ts | Defines TypeInfo, TypeInfoContext, and TypeInfoProvider types. |
| packages/compiler/src/core/program.ts | Adds provider registration and getTypeInfo implementation with design-time crash handling. |
| packages/compiler/src/core/library.ts | Adds defineTypeInfoProvider typing helper. |
| packages/compiler/src/core/features.ts | Registers the type-info-provider compiler feature with a description. |
| packages/compiler/src/core/external-error.ts | Extends ExternalError to support $provideTypeInfo crash reporting. |
| packages/compiler/src/core/binder.ts | Discovers $provideTypeInfo exports and registers them when feature is enabled per declaring project/library. |
| packages/bundler/src/bundler.ts | Bundles a library’s tspconfig.yaml so per-library feature opt-ins persist in browser bundles. |
| .chronus/changes/provide-type-info-http-route-2026-7-30-12-30-0.md | Changelog entry for @typespec/http type info provider. |
| .chronus/changes/provide-type-info-2026-7-30-12-30-0.md | Changelog entry for compiler API/hook introduction. |
| .chronus/changes/on-info-bundler-tspconfig-2026-7-31-9-30-0.md | Changelog entry for bundler preserving tspconfig.yaml in bundles. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Avoids maintaining two divergent implementations of the symbol->type resolution logic in the language server type details.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.
Suppressed comments (2)
Previously missed (2) — in code that hasn't changed since the last review.
packages/compiler/src/core/program.ts:337
getTypeInforeuses the samecontextobject for all providers. A misbehaving provider could mutatecontext(e.g. replacetarget) and affect subsequent providers, producing incorrect merged results. Passing a fresh context object per provider prevents cross-provider interference at minimal cost.
const context: TypeInfoContext = { program, target };
for (const provider of typeInfoProviders) {
let result: TypeInfo | undefined;
try {
result = provider.callback(context);
packages/http/src/type-info.ts:19
getHttpOperationalways returns anHttpOperationas the first tuple element, so theif (!operation)branch is dead code and impliesoperationcan be undefined when it cannot. This also prevents TypeScript from helping catch real nullability issues.
const [operation] = getHttpOperation(program, target);
if (!operation) {
return undefined;
}
Fixes #1993
Fixes #4860 (http specific info)
Summary
Adds a new experimental
$provideTypeInfolibrary provider andprogram.getTypeInfo(type)API that lets libraries contribute extra, domain-specific information about types. This information is surfaced in IDE hover tooltips and can be queried programmatically by tooling (e.g. AI agents).Unlike
$onValidate, a provider:The feature is gated behind a new
type-info-providercompiler feature flag, scoped to the package declaring it: a library opts in via its owntspconfig.yamland consumers do not need to enable anything.