Connecting CoValues with direct linking

CoValues can form relationships with each other by linking directly to other CoValues. This creates a powerful connection where one CoValue can point to the unique identity of another. Instead of embedding all the details of one CoValue directly within another, you use its Jazz-Tools schema as the field type. This allows multiple CoValues to point to the same piece of data effortlessly.

import { import coco, import zz, 
type Loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...
Loaded
, class Group
@categoryIdentity & Permissions
Group
, class Account
@categoryIdentity & Permissions
Account
} from "jazz-tools";
export const
const Location: CoMapSchema<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>
Location
= import coco.
map<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>(shape: {
    city: z.z.ZodString;
    country: z.z.ZodString;
}): CoMapSchema<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>
export map
map
({
city: z.z.ZodStringcity: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
(),
country: z.z.ZodStringcountry: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
(),
}); export type
type Location = {
    city: string;
    country: string;
} & CoMap
Location
= import coco.
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...
export loaded
loaded
<typeof
const Location: CoMapSchema<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>
Location
>;
// co.ref can be used within CoMap fields to point to other CoValues const
const Actor: CoMapSchema<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>
Actor
= import coco.
map<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>(shape: {
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}): CoMapSchema<...>
export map
map
({
name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodStringname: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
,
imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodStringimageURL: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
,
birthplace: CoMapSchema<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>
birthplace
:
const Location: CoMapSchema<{
    city: z.z.ZodString;
    country: z.z.ZodString;
}>
Location
// Links directly to the Location CoMap above.
}) export type
type Actor = {
    name: never;
    imageURL: never;
    birthplace: ({
        city: string;
        country: string;
    } & CoMap) | null;
} & CoMap
Actor
= import coco.
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...
export loaded
loaded
<typeof
const Actor: CoMapSchema<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>
Actor
>;
// actual actor data is stored in the separate Actor CoValue const
const Movie: CoMapSchema<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>
Movie
= import coco.
map<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>(shape: {
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}): CoMapSchema<...>
export map
map
({
title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodStringtitle: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
,
director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodStringdirector: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
,
cast: CoListSchema<CoMapSchema<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>>
cast
: import coco.
list<CoMapSchema<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>>(element: CoMapSchema<...>): CoListSchema<...>
export list
list
(
const Actor: CoMapSchema<{
    name: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    imageURL: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    birthplace: CoMapSchema<...>;
}>
Actor
), // ordered, mutable
}) export type
type Movie = {
    title: never;
    director: never;
    cast: CoList<({
        name: never;
        imageURL: never;
        birthplace: ({
            city: string;
            country: string;
        } & CoMap) | null;
    } & CoMap) | null> | null;
} & CoMap
Movie
= import coco.
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...
export loaded
loaded
<typeof
const Movie: CoMapSchema<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>
Movie
>;
// A User CoMap can maintain a CoFeed of co.ref(Movie) to track their favorite movies const
const User: CoMapSchema<{
    username: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    favoriteMovies: CoFeedSchema<CoMapSchema<{
        title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        cast: CoListSchema<...>;
    }>>;
}>
User
= import coco.
map<{
    username: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    favoriteMovies: CoFeedSchema<CoMapSchema<{
        title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        cast: CoListSchema<...>;
    }>>;
}>(shape: {
    username: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    favoriteMovies: CoFeedSchema<CoMapSchema<{
        title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        cast: CoListSchema<...>;
    }>>;
}): CoMapSchema<...>
export map
map
({
username: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodStringusername: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
,
favoriteMovies: CoFeedSchema<CoMapSchema<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>>
favoriteMovies
: import coco.
feed<CoMapSchema<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>>(element: CoMapSchema<...>): CoFeedSchema<...>
export feed
feed
(
const Movie: CoMapSchema<{
    title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    cast: CoListSchema<...>;
}>
Movie
), // append-only
}) export type
type User = {
    username: never;
    favoriteMovies: CoFeed<({
        title: never;
        director: never;
        cast: CoList<({
            name: never;
            imageURL: never;
            birthplace: ({
                city: string;
                country: string;
            } & CoMap) | null;
        } & CoMap) | null> | null;
    } & CoMap) | null> | null;
} & CoMap
User
= import coco.
type loaded<T extends CoValueClass | AnyCoSchema, R extends ResolveQuery<T> = true> = R extends boolean | undefined ? NonNullable<InstanceOfSchemaCoValuesNullable<T>> : [NonNullable<InstanceOfSchemaCoValuesNullable<T>>] extends [...] ? Exclude<...> extends CoValue ? R extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...> extends CoValue ? ItemDepth extends {
    ...;
} ? ((CoValue & ... 1 more ... & (ItemDepth extends boolean | undefined ? CoValue & Exclude<...> : [...] extends [...] ? Exclude<...
export loaded
loaded
<typeof
const User: CoMapSchema<{
    username: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
    favoriteMovies: CoFeedSchema<CoMapSchema<{
        title: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        director: (params?: string | z.z.core.$ZodStringParams) => z.z.ZodString;
        cast: CoListSchema<...>;
    }>>;
}>
User
>;

Understanding CoList and CoFeed

  • CoList is a collaborative list where each item is a reference to a CoValue
  • CoFeed contains an append-only list of references to CoValues.

This direct linking approach offers a single source of truth. When you update a referenced CoValue, all other CoValues that point to it are automatically updated, ensuring data consistency across your application.

By connecting CoValues through these direct references, you can build robust and collaborative applications where data is consistent, efficient to manage, and relationships are clearly defined. The ability to link different CoValue types to the same underlying data is fundamental to building complex applications with Jazz.

Recursive references with DiscriminatedUnion

In advanced schemas, you may want a CoValue that recursively references itself. For example, a ReferenceItem that contains a list of other items like NoteItem or AttachmentItem. This is common in tree-like structures such as threaded comments or nested project outlines.

You can model this with a Zod z.discriminatedUnion, but TypeScript’s type inference doesn't handle recursive unions well without a workaround.

Here’s how to structure your schema to avoid circular reference errors.

Use this pattern for recursive discriminated unions

import { 
type CoListSchema<T extends z.core.$ZodType> = z.z.core.$ZodArray<T> & {
    collaborative: true;
    create: (items: CoListInit<T>, options?: {
        owner: Account | Group;
    } | Account | Group) => CoList<InstanceOrPrimitiveOfSchema<T>>;
    load<const R extends RefsToResolve<CoListInstanceCoValuesNullable<T>> = true>(id: string, options?: {
        resolve?: RefsToResolveStrict<CoListInstanceCoValuesNullable<T>, R>;
        loadAs?: Account | AnonymousJazzAgent;
    }): Promise<Resolved<CoListInstanceCoValuesNullable<T>, R> | null>;
    subscribe<const R extends RefsToResolve<CoListInstanceCoValuesNullable<T>> = true>(id: string, options: SubscribeListenerOptions<CoListInstanceCoValuesNullable<T>, R>, listener: (value: Resolved<CoListInstanceCoValuesNullable<T>, R>, unsubscribe: () => void) => void): () => void;
    withHelpers<S extends z.z.core.$ZodType, T extends object>(this: S, helpers: (Self: S) => T): WithHelpers<S, T>;
    getCoSchema: () => typeof CoList;
}
CoListSchema
, import coco, import zz } from "jazz-tools";
// Recursive item modeling pattern using discriminated unions // First, define the non-recursive types export const
const NoteItem: CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>
NoteItem
= import coco.
map<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>(shape: {
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}): CoMapSchema<...>
export map
map
({
type: z.z.ZodLiteral<"note">type: import zz.
literal<"note">(value: "note", params?: string | z.z.core.$ZodLiteralParams): z.z.ZodLiteral<"note"> (+1 overload)
export literal
literal
("note"),
internal: z.z.ZodBooleaninternal: import zz.
function boolean(params?: string | z.z.core.$ZodBooleanParams): z.z.ZodBoolean
export boolean
boolean
(),
content: PlainTextSchemacontent: import coco.
function plainText(): PlainTextSchema
export plainText
plainText
(),
}); export const
const AttachmentItem: CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>
AttachmentItem
= import coco.
map<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>(shape: {
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}): CoMapSchema<...>
export map
map
({
type: z.z.ZodLiteral<"attachment">type: import zz.
literal<"attachment">(value: "attachment", params?: string | z.z.core.$ZodLiteralParams): z.z.ZodLiteral<"attachment"> (+1 overload)
export literal
literal
("attachment"),
internal: z.z.ZodBooleaninternal: import zz.
function boolean(params?: string | z.z.core.$ZodBooleanParams): z.z.ZodBoolean
export boolean
boolean
(),
content: FileStreamSchemacontent: import coco.
function fileStream(): FileStreamSchema
export fileStream
fileStream
(),
}); export const
const ReferenceItem: CoMapSchema<{
    type: z.z.ZodLiteral<"reference">;
    internal: z.z.ZodBoolean;
    content: z.z.ZodString;
    readonly children: CoListSchema<z.ZodDiscriminatedUnion<[typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]>>;
}>
ReferenceItem
= import coco.
map<{
    type: z.z.ZodLiteral<"reference">;
    internal: z.z.ZodBoolean;
    content: z.z.ZodString;
    readonly children: CoListSchema<z.ZodDiscriminatedUnion<[typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]>>;
}>(shape: {
    type: z.z.ZodLiteral<"reference">;
    internal: z.z.ZodBoolean;
    content: z.z.ZodString;
    readonly children: CoListSchema<z.ZodDiscriminatedUnion<[typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]>>;
}): CoMapSchema<...>
export map
map
({
type: z.z.ZodLiteral<"reference">type: import zz.
literal<"reference">(value: "reference", params?: string | z.z.core.$ZodLiteralParams): z.z.ZodLiteral<"reference"> (+1 overload)
export literal
literal
("reference"),
internal: z.z.ZodBooleaninternal: import zz.
function boolean(params?: string | z.z.core.$ZodBooleanParams): z.z.ZodBoolean
export boolean
boolean
(),
content: z.z.ZodStringcontent: import zz.
function string(params?: string | z.z.core.$ZodStringParams): z.z.ZodString
export string
string
(),
// Workaround: declare the field type using CoListSchema and ZodDiscriminatedUnion so TS can safely recurse get
children: CoListSchema<z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>>
children
():
type CoListSchema<T extends z.core.$ZodType> = z.z.core.$ZodArray<T> & {
    collaborative: true;
    create: (items: CoListInit<T>, options?: {
        owner: Account | Group;
    } | Account | Group) => CoList<InstanceOrPrimitiveOfSchema<T>>;
    load<const R extends RefsToResolve<CoListInstanceCoValuesNullable<T>> = true>(id: string, options?: {
        resolve?: RefsToResolveStrict<CoListInstanceCoValuesNullable<T>, R>;
        loadAs?: Account | AnonymousJazzAgent;
    }): Promise<Resolved<CoListInstanceCoValuesNullable<T>, R> | null>;
    subscribe<const R extends RefsToResolve<CoListInstanceCoValuesNullable<T>> = true>(id: string, options: SubscribeListenerOptions<CoListInstanceCoValuesNullable<T>, R>, listener: (value: Resolved<CoListInstanceCoValuesNullable<T>, R>, unsubscribe: () => void) => void): () => void;
    withHelpers<S extends z.z.core.$ZodType, T extends object>(this: S, helpers: (Self: S) => T): WithHelpers<S, T>;
    getCoSchema: () => typeof CoList;
}
CoListSchema
<import zz.
interface ZodDiscriminatedUnion<Options extends readonly core.$ZodType[] = readonly core.$ZodType<unknown, unknown>[]>
export ZodDiscriminatedUnion
ZodDiscriminatedUnion
<[typeof
const NoteItem: CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>
NoteItem
, typeof
const AttachmentItem: CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>
AttachmentItem
, typeof
const ReferenceItem: CoMapSchema<{
    type: z.z.ZodLiteral<"reference">;
    internal: z.z.ZodBoolean;
    content: z.z.ZodString;
    readonly children: CoListSchema<z.ZodDiscriminatedUnion<[typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]>>;
}>
ReferenceItem
]>> {
return
const ProjectContextItemList: CoListSchema<z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>>
ProjectContextItemList
;
}, }); // Create the recursive union export const
const ProjectContextItem: z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>
ProjectContextItem
= import zz.
discriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>(discriminator: string, options: [...], params?: string | z.z.core.$ZodDiscriminatedUnionParams): z.ZodDiscriminatedUnion<...>
export discriminatedUnion
discriminatedUnion
("type", [
const NoteItem: CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>
NoteItem
,
const AttachmentItem: CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>
AttachmentItem
,
const ReferenceItem: CoMapSchema<{
    type: z.z.ZodLiteral<"reference">;
    internal: z.z.ZodBoolean;
    content: z.z.ZodString;
    readonly children: CoListSchema<z.ZodDiscriminatedUnion<[typeof NoteItem, typeof AttachmentItem, typeof ReferenceItem]>>;
}>
ReferenceItem
]);
// Final list of recursive types export const
const ProjectContextItemList: CoListSchema<z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>>
ProjectContextItemList
= import coco.
list<z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>>(element: z.ZodDiscriminatedUnion<...>): CoListSchema<...>
export list
list
(
const ProjectContextItem: z.ZodDiscriminatedUnion<[CoMapSchema<{
    type: z.z.ZodLiteral<"note">;
    internal: z.z.ZodBoolean;
    content: PlainTextSchema;
}>, CoMapSchema<{
    type: z.z.ZodLiteral<"attachment">;
    internal: z.z.ZodBoolean;
    content: FileStreamSchema;
}>, CoMapSchema<...>]>
ProjectContextItem
);

Even though this seems like a shortcut, TypeScript and Zod can't resolve the circular reference this way. Always define the discriminated union before introducing recursive links.