Skip to content

1.15.0

  • #11552 using statements declared before a file-level(blockless) namespace are now resolved from the global namespace instead of the file namespace, matching C#.

    using TypeSpec.Http; // Now resolves the global `TypeSpec` namespace instead of `_Specs_.TypeSpec`
    namespace _Specs_.TypeSpec.Foo;

    A using declared after the file namespace, or inside a namespace block, is unchanged and still resolves relative to that namespace. Code relying on a relative name in a using written above the file namespace must now use the fully qualified name.

    namespace MyOrg.Service;
    using Models; // Still resolves to `MyOrg.Models`
  • #11476 Add back empty project template to tsp init options

    # Result of selecting "Empty project" in tsp init
    # main.tsp - minimal empty file to start from
  • #11000 Add setAutoDecorator API to programmatically apply an auto decorator to a target, mirroring what the synthesized auto dec implementation does when the decorator is written in source. This lets emitters and mutators mark synthetic types without reaching into the program state map directly.

    import { setAutoDecorator } from "@typespec/compiler";
    setAutoDecorator(program, "MyLib.myFlag", target);
  • #11468 Add Fix all: X code action for codefixes that can be applied to multiple instances in a file at once. When a codefix applies to more than one diagnostic of the same kind in a file, a Fix all: <fix label> quick fix action is now suggested alongside the individual fix.

  • #11209 Add support for short diagnostic and linter rule names. Diagnostic/rule codes can now be referenced by their scope-stripped short name (e.g. http/no-foo instead of @typespec/http/no-foo) or by a library-declared alias, both in #suppress directives and in the linter section of tspconfig.yaml. The full name is always accepted.

    model Post {
    #suppress "http/no-service-found" "standard library route"
    author: LegacyUser;
    }

    Libraries can declare a custom alias:

    export const $lib = createTypeSpecLibrary({
    name: "@azure-tools/typespec-client-generator-core",
    alias: "tcgc",
    diagnostics: {/* ... */},
    } as const);

    An alias must be kebab-case (lowercase letters, digits, and hyphens). When two loaded libraries would resolve to the same short name, that short name is ambiguous: referencing it (in a #suppress directive or the linter config) reports a warning and the full name must be used.

  • #11366 Language server folding ranges now report a kind: comments fold as comment and consecutive import statements fold together as an imports region. This enables editor commands such as “Fold All Block Comments” and “Fold All Imports” to work with TypeSpec files.

  • #11318 Add currentStage property and useCache method to Program for stage-aware caching. currentStage tracks the compilation pipeline stage (parsing → checking → validating → linting → emitting), and useCache provides a generic caching mechanism that libraries can use to avoid redundant computation during later stages.

  • #11221 Add a docs field to linter rule and diagnostic definitions to provide extended reference documentation. The value can be an inline markdown string or a FileRef created with fileRef.fromPackageRoot("src/rules/my-rule.md"), which is read lazily by tooling so it stays safe to bundle for the browser.

    export const myRule = createRule({
    name: "my-rule",
    severity: "warning",
    description: "Short description.",
    docs: fileRef.fromPackageRoot("src/rules/my-rule.md"),
    messages: {/* ... */},
    });
  • #11000 createTester now mounts each discovered library’s tspconfig.yaml into the virtual file system, so experimental features a library opts into (e.g. auto-decorators) are honored when compiling against the tester.

  • #11318 Cache getHttpOperation results during linting and emitting stages using program.useCache(). This eliminates redundant route resolution when multiple linter rules inspect the same operations, improving linter performance on large specs.
  • #11153 Add scope support to OpenIdConnectAuth. The model now accepts an optional Scopes template parameter (OpenIdConnectAuth<ConnectUrl, Scopes>) and the OpenAPI3 emitter emits those scopes on each operation’s openIdConnect security requirement. The scheme object itself remains unchanged (scopes are discovered via the openIdConnectUrl). Existing OpenIdConnectAuth<Url> usages are unaffected.
  • #11309 Add identifier field to the License model in @typespec/openapi. This is an SPDX license expression for the API (e.g. "MIT", "Apache-2.0"). The identifier and url fields are mutually exclusive. For OpenAPI 3.1+, identifier is emitted as-is; for OpenAPI 3.0, it is emitted as the x-oai-license-identifier extension. Importing an OpenAPI document also supports reading back identifier (or x-oai-license-identifier for 3.0 documents).

    @info(#{ license: #{ name: "MIT", identifier: "MIT" } })
    namespace MyService;
  • #11309 Add identifier field to the License model in @typespec/openapi. This is an SPDX license expression for the API (e.g. "MIT", "Apache-2.0"). The identifier and url fields are mutually exclusive. For OpenAPI 3.1+, identifier is emitted as-is; for OpenAPI 3.0, it is emitted as the x-oai-license-identifier extension. Importing an OpenAPI document also supports reading back identifier (or x-oai-license-identifier for 3.0 documents).

    @info(#{ license: #{ name: "MIT", identifier: "MIT" } })
    namespace MyService;
  • #11154 Extend the enum-strategy: annotated emitter option to unions of literals. When set to annotated, a union whose variants are literals is emitted as a oneOf/anyOf of const subschemas with per-variant title/description taken from @summary and @doc, instead of collapsing to a single lossy enum. Supported for OpenAPI 3.1.0 and above; emitting with OpenAPI 3.0.0 falls back to the default form and reports a warning.

    For example, the following TypeSpec:

    /** Set of known error types. */
    union ErrorType {
    /** Common error for a bad request. */
    @summary("CommonBadRequest")
    commonBadRequest: "https://example.com/errors/bad-request",
    /** The request body could not be parsed. */
    @summary("InvalidBody")
    invalidBody: "https://example.com/errors/invalid-body",
    }

    emits:

    ErrorType:
    description: Set of known error types.
    anyOf:
    - const: https://example.com/errors/bad-request
    title: CommonBadRequest
    description: Common error for a bad request.
    - const: https://example.com/errors/invalid-body
    title: InvalidBody
    description: The request body could not be parsed.

    Use @oneOf on the union to emit oneOf instead of anyOf.

  • #11153 Add scope support to OpenIdConnectAuth. The model now accepts an optional Scopes template parameter (OpenIdConnectAuth<ConnectUrl, Scopes>) and the OpenAPI3 emitter emits those scopes on each operation’s openIdConnect security requirement. The scheme object itself remains unchanged (scopes are discovered via the openIdConnectUrl). Existing OpenIdConnectAuth<Url> usages are unaffected.

  • #11477 Fix decorators running with unresolved template parameters when a decorated template is used as a template parameter default of an operation (e.g. op foo<Resource, Properties = Decorated<Resource>>(...), the ARM TagsUpdateModel<Resource> pattern). Operations now enter the template declaration scope before resolving template parameter defaults, so decorators on those defaults are no longer executed with the still-unresolved template parameter. This matches the existing behavior for models and interfaces.
  • #11423 tsp compile . now resolves the entrypoint from exports["."]["typespec"] in package.json, taking precedence over the legacy tspMain field
  • #11485 Report better error message when specifying an emitter that is not installed with --emit flag
  • #11426 IDE completion no longer adds unnecessary backticks when completing keyword identifiers in positions where they are allowed (model properties, object literal properties, member expressions).
  • #11467 tsp init template compilerVersion field now supports semver ranges (e.g., ^0.50.0). Plain versions like 1.2.3 continue to work as >=1.2.3 for backward compatibility.
  • #11427 Fix duplicate type name error when a model with a @visibility(Lifecycle.Create, Lifecycle.Update) property extends another model.
  • #11538 [converter] Convert query parameters using spaceDelimited/pipeDelimited styles to @encode(ArrayEncoding.spaceDelimited)/@encode(ArrayEncoding.pipeDelimited) instead of dropping them, including when explode: true is set
  • #11505 Use explicit @id values for bundled $defs keys to avoid silent overwrites.
  • #11283 Fix a shell command injection in the tsp compile task provider. Tasks now run via vscode.ProcessExecution with arguments passed as an array instead of vscode.ShellExecution, so workspace file paths and task arguments are no longer interpreted by the OS shell. The task args is now specified as an array of arguments.
  • #11543 Add missing-documentation and extraneous-documentation rules

    missing-documentation reports public declarations and members of a library that have no doc comment or @doc, so gaps in the generated reference documentation are caught at build time.

    extraneous-documentation reports doc comments that document something that doesn’t exist, such as a @param naming a parameter the operation doesn’t have, a @template copied from an enclosing interface, or an unescaped code reference the parser mistook for a tag:

    /**
    * Creates or updates an instance of the resource.
    * @template Resource The resource model. // `create` is not templated: the interface is
    */
    create(resource: Resource): Resource;

    Declarations in a Private namespace and declarations marked internal are excluded.

  • #11565 Add ./mutation-engine subpath export for standalone mutation pipeline usage