TypeSpec

Describe APIs
Describe your data up front and generate schemas, API specifications, client / server code, docs, and more.
main.tsp
import "@typespec/http";
using TypeSpec.Http;
model Store {
name: string;
address: Address;
}
model Address {
street: string;
city: string;
}
@route("/stores")
interface Stores {
list(@query filter: string): Store[];
read(@path id: Store): Store;
}
openapi.yaml
openapi: 3.0.0
info:
title: (title)
version: 0.0.0
tags: []
paths:
/stores:
get:
operationId: Stores_list
parameters:
- name: filter
in: query
required: true
schema:
type: string
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Store'
/stores/{id}:
get:
operationId: Stores_read
parameters:
- name: id
in: path
required: true
schema:
$ref: '#/components/schemas/Store'
responses:
'200':
description: The request has succeeded.
content:
application/json:
schema:
$ref: '#/components/schemas/Store'
components:
schemas:
Address:
type: object
required:
- street
- city
properties:
street:
type: string
city:
type: string
Store:
type: object
required:
- name
- address
properties:
name:
type: string
address:
$ref: '#/components/schemas/Address'
Why TypeSpec
API-First for developers
With TypeSpec, remove the handwritten files that slow you down, and generate standards-compliant API schemas in seconds.
Lightweight language for defining APIs
Inspired by TypeScript, TypeSpec is a minimal language that helps developers describe API shapes in a familiar way.
Learn more →
Easy integration with your toolchain
Write TypeSpec, emit to various formats and integrate with their ecosystems.
Multi-protocol support
TypeSpec's standard library includes support for OpenAPI 3.0, JSON Schema 2020-12 and Protobuf.
Learn more →
~ /my-project tsp init
? Select a template
Empty project
> REST API
Productivity
Streamline your OpenAPI workflow
Benefit from a huge ecosystem of OpenAPI tools for configuring API gateways, generating code, and validating your data.
Generate OpenAPI from TypeSpec
Learn more →
import "@typespec/http";
using TypeSpec.Http;
model Pet {
name: string;
age: int32;
}
model Store {
name: string;
address: Address;
}
model Address {
street: string;
city: string;
}
@route("/pets")
interface Pets {
list(@query filter: string): Pet[];
create(@body pet: Pet): Pet;
read(@path id: string): Pet;
}
@route("/stores")
interface Stores {
list(@query filter: string): Store[];
read(@path id: string): Store;
}
Ecosystem
Ensure data consistency
Define common models to use across your APIs, use the JSON schema emitter to get the JSON schema for your types and use them to validate your data.
JSON schema emitter reference
Learn more →
import "./common.tsp";
namespace MyOrg.Accounts;
using MyOrg.Types;
model Account {
id: id;
firstName: string;
lastName: string;
createdAt: utcDateTime;
// Use imported type by name only when using `using`
ssn: ssn;
// Or use the fully qualified name
email: MyOrg.Types.email;
balance: Amount;
}
model Amount {
value: decimal128;
currency: Currency;
}
// Create your own error types by extending the Error type
model AccountError is Error<"duplicate-account" | "invalid-account">;
op createAccount(account: Account): Account;
op charge(accountId: id, amount: Amount): void | AccountError;
Tooling
Full language support in VS Code and Visual Studio
TypeSpec provides built-in support for many common editor features such as syntax highlighting, code completion, and more.
Check out our available tooling
Learn more →
Extensibility
Generate assets in many formats
TypeSpec is built around extensibility - you can write your own emitter or add custom metadata using a new decorator.
Getting started with writing a library
Learn more →
lib.tsp
extern dec group(target: TypeSpec.Reflection.Model, name: valueof string);
lib.ts
import { DecoratorContext, EmitContext, Model, resolvePath } from "@typespec/compiler";
export async function $onEmit(context: EmitContext) {
const outputDir = resolvePath(context.emitterOutputDir, "hello.txt");
await context.program.host.writeFile(outputDir, "hello world!");
}
const groupKey = Symbol.for("my-library/group");
export function $group(context: DecoratorContext, target: Model, value: string) {
context.program.stateMap(groupKey).set(target, value);
}
Start your TypeSpec journey
Install the TypeSpec CLI or check out the playground to get started.