TypeScript Support
TeamPlay's TypeScript support connects three things:
- schemas define the document shape
- model classes define custom methods
- generated module augmentation tells TypeScript which schema and model belong to each path
If you use file-based models, TeamPlay generates the augmentation for you in teamplay-env.d.ts.
The Usual Setup
Add the Babel plugin and put models in models/:
The plugin writes teamplay-env.d.ts in the project root. Make sure your TypeScript config includes it:
Many app configs already include root .d.ts files through **/*.ts or **/*.tsx; add the file only if your editor or checker does not see it.
If your generated imports include explicit .ts extensions, enable a modern resolver such as moduleResolution: "Bundler" or moduleResolution: "NodeNext". For projects that import schema modules with explicit .ts extensions, also enable allowImportingTsExtensions.
Infer Document Types From Schemas
With file-based models, TeamPlay generates a default document type for every collection schema module. Define the schema with defineSchema() and export it as default:
After teamplay-env.d.ts is generated, the schema module's default export is also usable as the document type:
User becomes:
Plain exported schema objects still work, but defineSchema() is the conventional form and preserves literal inference without as const.
Type Model Classes
Collection models extend Signal<Document[]>:
Document models extend Signal<Document>:
Inside model methods, schema fields are typed signals:
Use Typed Root Paths
After teamplay-env.d.ts is generated, $ knows your collections:
sub() and useSub() preserve the same schema and model type:
Query params are checked against the schema:
Literal dotted paths are checked too:
Computed Mongo-style paths are allowed, but TypeScript cannot validate the specific field behind a runtime string:
Aggregation output types are output-first:
For grouped or metadata output, pass that full result shape:
Type Component Props
Use Signal<T> for signal props:
Signal<User> also includes the generated document model methods when User matches one known collection document type.
For query, collection, or list props, use the array document type. The signal keeps the collection model methods, and item signals keep the document model methods:
This also works for query results from sub() and useSub():
Top-level collection, query, and aggregation signals are array-readable with map, reduce, find, and iteration. Array mutators such as push and pop are only typed on actual array fields like $user.tags, because mutating a collection or query result as an array is not a valid runtime operation.
If two collections have exactly the same document type, TeamPlay cannot safely infer which collection model belongs to Signal<T>, so it falls back to the plain typed signal shape.
Query signals have typed metadata children:
ids and extra are reserved on query signals. If a document id has the same name, access it from the collection object tree:
Local Signals
Local signals infer types from their initial value:
You can also provide the type explicitly:
This gives TypeScript the signal shape, but the runtime value is still uninitialized until you set or assign it.
Private Root Types
Schemas under private root collections describe the private value itself, not documents inside a database collection:
The generated file registers that schema in TeamplayPrivateCollections, so the root signal aliases are typed:
Private root signals are value signals. They are not collection signals and do not expose .add().
Nested Models
Nested files are generated into TeamplayModels:
Then:
Field Descriptions In Editor Suggestions
For simple schema files, TeamPlay generates field JSDoc from literal label and description values:
Editors can show that text when completing:
The generator supports common static forms:
If the schema is dynamic or cannot be parsed safely, field JSDoc is skipped but the normal schema type can still work through TypeScript.
How The Generated File Works
teamplay-env.d.ts augments the teamplay module and each schema module:
- Schema module augmentation makes
import type User from './models/users/schema.ts'work. TeamplayCollectionsregisters collection schemas, collection model classes, and document model classes.TeamplayPrivateCollectionsregisters private root value schemas such as_session.TeamplayModelsregisters extra model classes below documents.TeamplaySignalFieldspreserves schema field JSDoc in signal completions.
You normally do not edit this file.
Manual Augmentation
If you do not use file-based models, or if a framework/plugin provides models that the local filesystem cannot see, add an augmentation file included by your tsconfig.json.
Use actual model class constructors when they are importable. Use export declare class in .d.ts files when the runtime model class is registered somewhere else, such as package or framework sidecars.
For schemas, prefer JsonSchemaSpec:
Manual augmentation should match the runtime registration. If the runtime and type registry disagree, TypeScript may suggest methods that are not present at runtime.
Plugin And Framework Augmentation
Frameworks and plugin systems can contribute types through declaration files instead of asking each app to edit types/teamplay.ts manually. These interfaces are intentionally advanced integration points:
The root signal merges app collections with all registered plugin collections. Plugin declaration files can also expose static options and feature flags:
End applications usually receive these imports from their framework-generated teamplay-env.d.ts; normal app code should not need to wire them by hand.
Known Limits
TeamPlay keeps the object-tree document API as $.users[id]. TypeScript models that with broad string indexing, so it cannot perfectly distinguish every dynamic document id from every named collection property or model method. Named query metadata such as ids and extra stays precise, and bracket access is the clearest form when a document id collides with a named property.
Schema Type Coverage
The type mapper covers the schema features used most often in TeamPlay apps:
- objects and nested properties
- arrays and tuple arrays
- strings, numbers, integers, booleans, and nulls
- enums and const values
required: [...]- field-level
required: truein simplified schemas additionalPropertiesandpatternProperties
Zod-like schemas can be used for type inference with ZodSchemaSpec, but TeamPlay does not currently convert Zod schemas to backend JSON Schema automatically. Use JSON Schema for runtime validation.