import * as __ctHelpers from "commontools"; import { computed, pattern, UI, NAME } from "commontools"; // Represents a question that may or may not exist type Question = { question: string; category: string; priority: number; }; export default pattern((_) => { // This computed can return null - simulates finding a question from a list const topQuestion = __ctHelpers.derive({ type: "object", properties: {} } as const satisfies __ctHelpers.JSONSchema, { anyOf: [{ $ref: "#/$defs/Question" }, { type: "null" }], $defs: { Question: { type: "object", properties: { question: { type: "string" }, category: { type: "string" }, priority: { type: "number" } }, required: ["question", "category", "priority"] } } } as const satisfies __ctHelpers.JSONSchema, {}, (): Question | null => { // In real code this would filter and return first match, or null return null; }); return { [NAME]: "Computed Nullable Optional Chain", [UI]: (
Optional chaining: {__ctHelpers.derive({ type: "object", properties: { topQuestion: { anyOf: [{ $ref: "#/$defs/Question" }, { type: "null" }], asOpaque: true } }, required: ["topQuestion"], $defs: { Question: { type: "object", properties: { question: { type: "string" }, category: { type: "string" }, priority: { type: "number" } }, required: ["question", "category", "priority"] } } } as const satisfies __ctHelpers.JSONSchema, { anyOf: [{ type: "string", asOpaque: true }, { type: "string", "enum": [""] }] } as const satisfies __ctHelpers.JSONSchema, { topQuestion: topQuestion }, ({ topQuestion }) => topQuestion?.question || "")}
{/* WORKAROUND: Explicit null check preserves nullability */} {/* This correctly generates anyOf [Question, null] in the schema */}Explicit check: {__ctHelpers.derive({ type: "object", properties: { topQuestion: { anyOf: [{ $ref: "#/$defs/Question" }, { type: "null" }], asOpaque: true } }, required: ["topQuestion"], $defs: { Question: { type: "object", properties: { question: { type: "string" }, category: { type: "string" }, priority: { type: "number" } }, required: ["question", "category", "priority"] } } } as const satisfies __ctHelpers.JSONSchema, { anyOf: [{ type: "string", asOpaque: true }, { type: "string", "enum": [""] }] } as const satisfies __ctHelpers.JSONSchema, { topQuestion: topQuestion }, ({ topQuestion }) => topQuestion === null ? "" : topQuestion.question)}
{/* Same issue with category field */} Category (buggy): {__ctHelpers.derive({ type: "object", properties: { topQuestion: { anyOf: [{ $ref: "#/$defs/Question" }, { type: "null" }], asOpaque: true } }, required: ["topQuestion"], $defs: { Question: { type: "object", properties: { question: { type: "string" }, category: { type: "string" }, priority: { type: "number" } }, required: ["question", "category", "priority"] } } } as const satisfies __ctHelpers.JSONSchema, { anyOf: [{ type: "string", asOpaque: true }, { type: "string", "enum": [""] }] } as const satisfies __ctHelpers.JSONSchema, { topQuestion: topQuestion }, ({ topQuestion }) => topQuestion?.category || "")} Category (works): {__ctHelpers.derive({ type: "object", properties: { topQuestion: { anyOf: [{ $ref: "#/$defs/Question" }, { type: "null" }], asOpaque: true } }, required: ["topQuestion"], $defs: { Question: { type: "object", properties: { question: { type: "string" }, category: { type: "string" }, priority: { type: "number" } }, required: ["question", "category", "priority"] } } } as const satisfies __ctHelpers.JSONSchema, { anyOf: [{ type: "string", asOpaque: true }, { type: "string", "enum": [""] }] } as const satisfies __ctHelpers.JSONSchema, { topQuestion: topQuestion }, ({ topQuestion }) => topQuestion === null ? "" : topQuestion.category)}