Client Options
This page documents how to use the @clientOption decorator to pass language-specific configuration options to emitters. For an overview of the setup, please visit the setup page.
Overview
Section titled “Overview”The @clientOption decorator allows spec authors to pass arbitrary key-value options to specific language emitters. This enables fine-grained control over code generation behavior that may vary between languages.
@clientOption(name: string, value: string | boolean | number, scope?: string)Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
name | string | The name of the option to set |
value | string | boolean | number | The value for the option |
scope | string (optional) | The target language scope. Required - omitting scope produces an additional warning |
Basic Usage
Section titled “Basic Usage”Apply the decorator to models, operations, enums, or properties with a language-specific scope:
import "@azure-tools/typespec-client-generator-core";
using Azure.ClientGenerator.Core;
#suppress "@azure-tools/typespec-client-generator-core/client-option"@clientOption("enableFeatureFoo", true, "python")model MyModel { id: string;}# The Python emitter can read this option from the model's decorators array# and apply the appropriate code generation behavior// C# emitter does not see this option (scoped to Python only)// TypeScript emitter does not see this option (scoped to Python only)// Java emitter does not see this option (scoped to Python only)// Go emitter does not see this option (scoped to Python only)Multiple Options
Section titled “Multiple Options”You can apply multiple @clientOption decorators to the same target:
#suppress "@azure-tools/typespec-client-generator-core/client-option"#suppress "@azure-tools/typespec-client-generator-core/client-option"@clientOption("enableFeatureFoo", true, "python")@clientOption("customSerializerMode", "strict", "python")model MyModel { id: string;}Different Value Types
Section titled “Different Value Types”The decorator supports string, boolean, and numeric values:
#suppress "@azure-tools/typespec-client-generator-core/client-option"@clientOption("booleanOption", true, "python")model BoolExample { id: string;}
#suppress "@azure-tools/typespec-client-generator-core/client-option"@clientOption("stringOption", "customValue", "csharp")model StringExample { id: string;}
#suppress "@azure-tools/typespec-client-generator-core/client-option"@clientOption("numericOption", 42, "java")model NumericExample { id: string;}How Emitters Access Client Options
Section titled “How Emitters Access Client Options”TCGC provides the getClientOptions helper function to easily extract client options from any SDK type that has a decorators array.
Using the getClientOptions Helper (Recommended)
Section titled “Using the getClientOptions Helper (Recommended)”import { getClientOptions } from "@azure-tools/typespec-client-generator-core";
// Get client options from a modelconst sdkModel = context.sdkPackage.models.find((m) => m.name === "MyModel");const clientOptions = getClientOptions(sdkModel.decorators);
for (const option of clientOptions) { console.log(`Option: ${option.name} = ${option.value}`); // option.name: string - The option name (e.g., "enableFeatureFoo") // option.value: string | boolean | number - The option value // option.scope?: string - The language scope (e.g., "python")}The getClientOptions function returns an array of SdkClientOption objects:
interface SdkClientOption { name: string; value: string | boolean | number; scope?: string;}Works with Any Decorated SDK Type
Section titled “Works with Any Decorated SDK Type”The helper works with any SDK type that has a decorators array:
// Modelsconst modelOptions = getClientOptions(sdkModel.decorators);
// Enumsconst enumOptions = getClientOptions(sdkEnum.decorators);
// Operations/Methodsconst methodOptions = getClientOptions(sdkMethod.decorators);
// Propertiesconst propertyOptions = getClientOptions(sdkProperty.decorators);
// Clientsconst clientOptions = getClientOptions(sdkClient.decorators);Alternative: Manual Decorator Filtering
Section titled “Alternative: Manual Decorator Filtering”If you need more control, you can also filter the decorators array directly:
const sdkModel = context.sdkPackage.models.find((m) => m.name === "MyModel");const clientOptionDecorators = sdkModel.decorators.filter( (d) => d.name === "Azure.ClientGenerator.Core.@clientOption",);
for (const decorator of clientOptionDecorators) { const optionName = decorator.arguments.name; // e.g., "enableFeatureFoo" const optionValue = decorator.arguments.value; // e.g., true const scope = decorator.arguments.scope; // e.g., "python"}Supported Client Options
Section titled “Supported Client Options”| Option Name | Value Type | Target | Languages | Description |
|---|---|---|---|---|
omitSlashFromEmptyRoute | boolean | Operation, Interface, Namespace | All | When true, operations with empty routes (path "/") will use "" instead. Only affects empty routes. |
#suppress "@azure-tools/typespec-client-generator-core/client-option" "legacy storage usage"@clientOption("omitSlashFromEmptyRoute", true, "python")@putop createBlob(): void;Best Practices
Section titled “Best Practices”-
Always specify a scope: The decorator is designed for language-specific behavior. Omitting the scope produces an additional warning.
-
Suppress the warning intentionally: Use
#suppress "@azure-tools/typespec-client-generator-core/client-option"to acknowledge that you’re using this advanced feature. -
Document usage: When using client options, document why they’re needed so future maintainers understand the intent.
-
Prefer standard decorators: Use standard TCGC decorators like
@clientName,@access,@usage, etc. when they can achieve the desired behavior. Reserve@clientOptionfor cases where no standard decorator exists. -
Coordinate with emitter teams: Before using a client option, verify with the target language emitter team that the option is supported and understand its behavior.