TypeScript Types
Monch provides comprehensive TypeScript support with full type inference from your schemas.
Type Inference
Types flow automatically from your Zod schema:
typescript
const Users = collection({
name: 'users',
schema: {
_id: field.id(),
name: field.string(),
email: field.email(),
role: field.enum(['user', 'admin']).default('user'),
},
timestamps: true,
});
// TypeScript automatically infers:
// - Document type includes all fields + timestamps
// - Input type respects defaults/optionals
// - Query results are typed
// - Serialized output is typedExtracting Types from Collections
The recommended way to get types:
typescript
import { collection, field, type ModelOf, type SerializedOf } from '@codician-team/monch';
export const Users = collection({
name: 'users',
schema: {
_id: field.id(),
name: field.string(),
email: field.email(),
},
timestamps: true,
});
// Extract types from the collection (includes timestamps!)
export type User = ModelOf<typeof Users>;
// { _id: ObjectId; name: string; email: string; createdAt: Date; updatedAt: Date }
export type SerializedUser = SerializedOf<typeof Users>;
// { _id: string; name: string; email: string; createdAt: string; updatedAt: string }Type Extraction Helpers
| Type Helper | Description |
|---|---|
ModelOf<C> | Extract document type from collection (includes timestamps) |
SerializedOf<C> | Extract serialized type from collection |
SchemaOf<C> | Extract the raw schema type from collection |
Schema Types
Build types from schemas directly:
typescript
import { type Doc, type Input, type Serialized } from '@codician-team/monch';
const userSchema = {
_id: field.id(),
name: field.string(),
email: field.email(),
};
// Document type (what's in MongoDB)
type User = Doc<typeof userSchema>;
// { _id: ObjectId; name: string; email: string }
// Input type (what you pass to insertOne)
type UserInput = Input<typeof userSchema>;
// { _id?: ObjectId | string; name: string; email: string }
// Serialized type (after .serialize())
type SerializedUser = Serialized<User>;
// { _id: string; name: string; email: string }Adding Timestamps Manually
typescript
import { type WithTimestamps } from '@codician-team/monch';
type User = Doc<typeof userSchema>;
type UserWithTimestamps = WithTimestamps<User>;
// { _id: ObjectId; name: string; email: string; createdAt: Date; updatedAt: Date }MonchFilter Type
For filter parameters that need to work with Zod-inferred types:
typescript
import { type MonchFilter } from '@codician-team/monch';
// MonchFilter is more permissive than MongoDB's Filter type
function findUsers(filter: MonchFilter<User>) {
return Users.find(filter).toArray();
}
// All of these work without type errors:
findUsers({ email: 'test@example.com' });
findUsers({ createdAt: { $gte: new Date() } });
findUsers({ 'profile.name': 'John' });
findUsers({ $or: [{ status: 'active' }, { role: 'admin' }] });All collection methods use MonchFilter internally, so you typically don't need to import it directly.
Importing Types
typescript
import {
// Schema types
type Doc, // Document type from schema
type Input, // Input type (respects defaults/optionals)
type Schema, // Schema definition type
// Operation types
type Filter, // MongoDB filter type (strict)
type UpdateFilter, // MongoDB update type
type MonchFilter, // Relaxed filter type (recommended)
// Serialization
type Serialized, // BSON -> plain JS conversion
// Type extraction (from collections)
type ModelOf, // Extract document type from collection
type SerializedOf, // Extract serialized type from collection
type SchemaOf, // Extract schema type from collection
// Utilities
type WithTimestamps, // Add createdAt/updatedAt to type
} from '@codician-team/monch';Using Types in Components
typescript
// lib/models/user.model.ts
import { collection, field, type ModelOf, type SerializedOf } from '@codician-team/monch';
export const Users = collection({
name: 'users',
schema: {
_id: field.id(),
name: field.string(),
email: field.email(),
avatar: field.url().optional(),
},
timestamps: true,
});
export type User = ModelOf<typeof Users>;
export type SerializedUser = SerializedOf<typeof Users>;typescript
// components/UserCard.tsx
import type { SerializedUser } from '@/lib/models/user.model';
interface UserCardProps {
user: SerializedUser;
}
export function UserCard({ user }: UserCardProps) {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
{user.avatar && <img src={user.avatar} alt={user.name} />}
<small>Joined {new Date(user.createdAt).toLocaleDateString()}</small>
</div>
);
}Type-Safe Server Actions
typescript
// app/actions/user.actions.ts
'use server';
import { Users, type User, type SerializedUser } from '@/lib/models';
export async function getUser(id: string): Promise<SerializedUser | null> {
const user = await Users.findById(id);
return user?.serialize() ?? null;
}
export async function updateUser(
id: string,
data: Partial<Pick<User, 'name' | 'avatar'>>
): Promise<SerializedUser | null> {
const user = await Users.updateOne(
{ _id: id },
{ $set: data }
);
return user?.serialize() ?? null;
}Generic Functions
Create type-safe generic functions:
typescript
import { type Collection, type ModelOf } from '@codician-team/monch';
async function findOrCreate<C extends Collection<any, any, any>>(
collection: C,
filter: object,
defaults: Partial<ModelOf<C>>
): Promise<ModelOf<C>> {
const existing = await collection.findOne(filter);
if (existing) return existing;
return collection.insertOne({
...defaults,
...filter,
} as any);
}
// Usage
const user = await findOrCreate(Users, { email: 'alice@example.com' }, {
name: 'Alice',
});Runtime Schema Access
Access the Zod schema at runtime for validation or introspection:
typescript
const Users = collection({
name: 'users',
schema: {
_id: field.id(),
name: field.string(),
email: field.email(),
},
});
// Access runtime schema
const schema = Users.$schema;
// Validate data manually
const result = schema.safeParse({ name: 'Alice', email: 'invalid' });
if (!result.success) {
console.log(result.error.issues);
}
// Create derived schemas
const PartialUser = schema.partial();
const UserWithExtra = schema.extend({ extra: z.string() });Collection Properties
| Property | Type | Description |
|---|---|---|
$schema | ZodObject | Runtime-accessible Zod schema |
$model | type only | Document type (use with typeof) |
$serialized | type only | Serialized document type (use with typeof) |