Defining types
By the end of this page the app will have its three types: organizations, the people who work at them, and the events they attend.
Before you start
Section titled “Before you start”A type is a schema with a name. ECHO uses the schema three ways:
- The compiler uses it to check the fields of every object you create.
- ECHO uses it to check what it stores, and to send the type to peers that have not seen it.
- Code can read it at run time. The app’s forms, table and graph are built from the schemas rather than written per type.
The schema is an Effect Schema. The name is a DXN: a reverse-domain name and a version, such as com.example.type.person at 0.1.0. Use a domain you control, since the name is global.
A field can hold a reference to another object, with Ref.Ref(Type). A reference stores the target’s identity, not a copy, so the graph stays consistent when the target changes.
-
Declare an organization.
Type.makeObjecttakes the name and the schema, and returns a class that is both the schema and the TypeScript type of its instances.export classOrganization extendsclass OrganizationType.import TypemakeObject<const makeObject: <Organization>(dxn: DXN.DXN, options?: {id?: EntityId;}) => Type.MakeObject<Organization>Factory function to create an ECHO object type.
Returns a
Type.Typeentity — a live, in-memoryTypeSchemainstance, NOT aSchema.Schema. UseType.InstanceType<typeof Foo>for the instance type andType.getSchema(Foo)to obtain the underlying Effect Schema.The entity's id defaults to
EntityId.deterministic(typename, version)so constructing a type never reachescrypto.getRandomValues()— required for Cloudflare workerd, which forbids RNG calls in global (module-evaluation) scope. Pass{ id }to override (e.g. withEntityId.random()from a request handler).Giving the type a nominal class name keeps its inferred type portable for declaration emit: structural expansion (which can pull in unnameable union members from referenced schemas) is replaced by a reference to the class.
The second call takes either a schema, or struct fields (wrapped in
Schema.Struct) with an optional function that pipes annotations onto the struct.Organization>(class OrganizationDXN.import DXNmake('com.example.type.organization', '0.1.0'))(const make: <"com.example.type.organization">(nsid: "com.example.type.organization", version?: string) => DXN.DXNConstructs a DXN from an NSID (and optional version). Throws if the result is not a valid DXN. Use
tryMakefor non-throwing string parsing.Static NSID strings are validated at compile time via
Name
: the final segment must be camelCase (no hyphens). Template-literal strings with a runtime prefix are accepted here but still validated at runtime.
Schema.import SchemaStruct({function Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>(fields: {readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}): Schema.Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's
Typeis a readonly object type with the fields' decoded types. TheEncodedform mirrors the field schemas' encoded types. Declared fields may be inherited and are copied to own properties in the output. The__proto__field is accepted only when it is an own property. Parsing does not guarantee that output keys retain their input order.Example (Defining a basic struct)
import { Schema } from "effect"const Person = Schema.Struct({name: Schema.String,age: Schema.Number,email: Schema.optionalKey(Schema.String)})// { readonly name: string; readonly age: number; readonly email?: string }type Person = typeof Person.TypeSchema.decodeUnknownSync(Person)({ name: "Alice", age: 30 }) // => { name: "Alice", age: 30 }name:name: Schema.StringSchema.import SchemaString,const String: Schema.StringType-level representation of
String
.
Schema for
stringvalues. Validates that the input istypeof"string".website:website: Schema.optional<Schema.String>Schema.import Schemaoptional(const optional: optionalLambda<Schema.String>(self: Schema.String) => Schema.optional<Schema.String>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.Details
The resulting property may be absent or explicitly set to
undefined. Equivalent tooptionalKey(UndefinedOr(S)).Use
optionalKey
instead if you want exact optional semantics (absent only, not
undefined).Example (Defining an optional field accepting undefined)
import { Schema } from "effect"const schema = Schema.Struct({name: Schema.String,age: Schema.optional(Schema.Number)})// { readonly name: string; readonly age?: number | undefined }type Person = typeof schema.TypeFormat.import FormatURL),const URL: Schema.String}).pipe(Pipeable.pipe<Schema.Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>, Schema.Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>) => Schema.Struct<{readonly name: Schema.String;readonly website: Schema.optional<Schema.String>;}>): Schema.Struct<...> (+21 overloads)Annotation.import AnnotationIconAnnotation.const IconAnnotation: Annotation.Annotation<Annotation.IconAnnotation>export IconAnnotationIcon to render in the UI.
set({Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <S extends Schema.Top>(schema: S) => SSet the annotation on an Effect schema.
Only accepts
Schema.Top— annotations must be applied to the source schema BEFORE wrapping it withType.makeObject/Type.makeRelation. In a pipe, place everyAnnotation.X.set(...)before theType.make...step.icon: 'ph--buildings--regular',icon: stringSprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').
ph--*is Phosphor;px--*anddx--*are brand glyphs, which are sprite-only and carry no weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic session, a GitHub repo — has no honest Phosphor equivalent.hue: 'amber' })),hue?: string | undefinedColor name.
List of colors:
- 'red'
- 'orange'
- 'amber'
- 'yellow'
- 'lime'
- 'green'
- 'emerald'
- 'teal'
- 'cyan'
- 'violet'
- 'purple'
- 'fuchsia'
- 'pink'
- 'rose'
) {}Format.URLmarks the website as a URL, so a form offers a URL field for it.IconAnnotationgives the type an icon and a hue, which the app’s list and graph use. -
Point a person at an organization.
employeris a reference to anOrganization.export classPerson extendsclass PersonType.import TypemakeObject<const makeObject: <Person>(dxn: DXN.DXN, options?: {id?: EntityId;}) => Type.MakeObject<Person>Factory function to create an ECHO object type.
Returns a
Type.Typeentity — a live, in-memoryTypeSchemainstance, NOT aSchema.Schema. UseType.InstanceType<typeof Foo>for the instance type andType.getSchema(Foo)to obtain the underlying Effect Schema.The entity's id defaults to
EntityId.deterministic(typename, version)so constructing a type never reachescrypto.getRandomValues()— required for Cloudflare workerd, which forbids RNG calls in global (module-evaluation) scope. Pass{ id }to override (e.g. withEntityId.random()from a request handler).Giving the type a nominal class name keeps its inferred type portable for declaration emit: structural expansion (which can pull in unnameable union members from referenced schemas) is replaced by a reference to the class.
The second call takes either a schema, or struct fields (wrapped in
Schema.Struct) with an optional function that pipes annotations onto the struct.Person>(class PersonDXN.import DXNmake('com.example.type.person', '0.1.0'))(const make: <"com.example.type.person">(nsid: "com.example.type.person", version?: string) => DXN.DXNConstructs a DXN from an NSID (and optional version). Throws if the result is not a valid DXN. Use
tryMakefor non-throwing string parsing.Static NSID strings are validated at compile time via
Name
: the final segment must be camelCase (no hyphens). Template-literal strings with a runtime prefix are accepted here but still validated at runtime.
Schema.import SchemaStruct({function Struct<{readonly name: Schema.String;readonly email: Schema.optional<Schema.String>;readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;}>(fields: {readonly name: Schema.String;readonly email: Schema.optional<Schema.String>;readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;}): Schema.Struct<...>Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's
Typeis a readonly object type with the fields' decoded types. TheEncodedform mirrors the field schemas' encoded types. Declared fields may be inherited and are copied to own properties in the output. The__proto__field is accepted only when it is an own property. Parsing does not guarantee that output keys retain their input order.Example (Defining a basic struct)
import { Schema } from "effect"const Person = Schema.Struct({name: Schema.String,age: Schema.Number,email: Schema.optionalKey(Schema.String)})// { readonly name: string; readonly age: number; readonly email?: string }type Person = typeof Person.TypeSchema.decodeUnknownSync(Person)({ name: "Alice", age: 30 }) // => { name: "Alice", age: 30 }name:name: Schema.StringSchema.import SchemaString,const String: Schema.StringType-level representation of
String
.
Schema for
stringvalues. Validates that the input istypeof"string".email:email: Schema.optional<Schema.String>Schema.import Schemaoptional(const optional: optionalLambda<Schema.String>(self: Schema.String) => Schema.optional<Schema.String>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.Details
The resulting property may be absent or explicitly set to
undefined. Equivalent tooptionalKey(UndefinedOr(S)).Use
optionalKey
instead if you want exact optional semantics (absent only, not
undefined).Example (Defining an optional field accepting undefined)
import { Schema } from "effect"const schema = Schema.Struct({name: Schema.String,age: Schema.optional(Schema.Number)})// { readonly name: string; readonly age?: number | undefined }type Person = typeof schema.TypeFormat.import FormatEmail),const Email: Schema.StringEmail address (RFC 5321). The local part also allows an apostrophe, which real mail carries (
o'day@corp.com). https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.2employer:employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>Schema.import Schemaoptional(const optional: optionalLambda<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>(self: Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>) => Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.Details
The resulting property may be absent or explicitly set to
undefined. Equivalent tooptionalKey(UndefinedOr(S)).Use
optionalKey
instead if you want exact optional semantics (absent only, not
undefined).Example (Defining an optional field accepting undefined)
import { Schema } from "effect"const schema = Schema.Struct({name: Schema.String,age: Schema.optional(Schema.Number)})// { readonly name: string; readonly age?: number | undefined }type Person = typeof schema.TypeRef.import RefRef(const Ref: <typeof Organization>(type: typeof Organization) => Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown> (+3 overloads)Organization)),class Organization}).pipe(Pipeable.pipe<Schema.Struct<{readonly name: Schema.String;readonly email: Schema.optional<Schema.String>;readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;}>, Schema.Struct<{readonly name: Schema.String;readonly email: Schema.optional<Schema.String>;readonly employer: Schema.optional<Ref.RefSchema<Organization & OfKind<EntityKind.Object> & Unknown>>;}>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<...>) => Schema.Struct<...>): Schema.Struct<...> (+21 overloads)Annotation.import AnnotationIconAnnotation.const IconAnnotation: Annotation.Annotation<Annotation.IconAnnotation>export IconAnnotationIcon to render in the UI.
set({Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <S extends Schema.Top>(schema: S) => SSet the annotation on an Effect schema.
Only accepts
Schema.Top— annotations must be applied to the source schema BEFORE wrapping it withType.makeObject/Type.makeRelation. In a pipe, place everyAnnotation.X.set(...)before theType.make...step.icon: 'ph--user--regular',icon: stringSprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').
ph--*is Phosphor;px--*anddx--*are brand glyphs, which are sprite-only and carry no weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic session, a GitHub repo — has no honest Phosphor equivalent.hue: 'cyan' })),hue?: string | undefinedColor name.
List of colors:
- 'red'
- 'orange'
- 'amber'
- 'yellow'
- 'lime'
- 'green'
- 'emerald'
- 'teal'
- 'cyan'
- 'violet'
- 'purple'
- 'fuchsia'
- 'pink'
- 'rose'
) {} -
Point an event at many people. A list of references gives an event its attendees.
LabelAnnotationsays which field names an event, since it has atitlerather than aname.export classEvent extendsclass EventType.import TypemakeObject<const makeObject: <Event>(dxn: DXN.DXN, options?: {id?: EntityId;}) => Type.MakeObject<Event>Factory function to create an ECHO object type.
Returns a
Type.Typeentity — a live, in-memoryTypeSchemainstance, NOT aSchema.Schema. UseType.InstanceType<typeof Foo>for the instance type andType.getSchema(Foo)to obtain the underlying Effect Schema.The entity's id defaults to
EntityId.deterministic(typename, version)so constructing a type never reachescrypto.getRandomValues()— required for Cloudflare workerd, which forbids RNG calls in global (module-evaluation) scope. Pass{ id }to override (e.g. withEntityId.random()from a request handler).Giving the type a nominal class name keeps its inferred type portable for declaration emit: structural expansion (which can pull in unnameable union members from referenced schemas) is replaced by a reference to the class.
The second call takes either a schema, or struct fields (wrapped in
Schema.Struct) with an optional function that pipes annotations onto the struct.Event>(class EventDXN.import DXNmake('com.example.type.event', '0.1.0'))(const make: <"com.example.type.event">(nsid: "com.example.type.event", version?: string) => DXN.DXNConstructs a DXN from an NSID (and optional version). Throws if the result is not a valid DXN. Use
tryMakefor non-throwing string parsing.Static NSID strings are validated at compile time via
Name
: the final segment must be camelCase (no hyphens). Template-literal strings with a runtime prefix are accepted here but still validated at runtime.
Schema.import SchemaStruct({function Struct<{readonly title: Schema.String;readonly description: Schema.optional<Schema.String>;readonly attendees: Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>;}>(fields: {readonly title: Schema.String;readonly description: Schema.optional<Schema.String>;readonly attendees: Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>;}): Schema.Struct<...>Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's
Typeis a readonly object type with the fields' decoded types. TheEncodedform mirrors the field schemas' encoded types. Declared fields may be inherited and are copied to own properties in the output. The__proto__field is accepted only when it is an own property. Parsing does not guarantee that output keys retain their input order.Example (Defining a basic struct)
import { Schema } from "effect"const Person = Schema.Struct({name: Schema.String,age: Schema.Number,email: Schema.optionalKey(Schema.String)})// { readonly name: string; readonly age: number; readonly email?: string }type Person = typeof Person.TypeSchema.decodeUnknownSync(Person)({ name: "Alice", age: 30 }) // => { name: "Alice", age: 30 }title:title: Schema.StringSchema.import SchemaString,const String: Schema.StringType-level representation of
String
.
Schema for
stringvalues. Validates that the input istypeof"string".description:description: Schema.optional<Schema.String>Schema.import Schemaoptional(const optional: optionalLambda<Schema.String>(self: Schema.String) => Schema.optional<Schema.String>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.Details
The resulting property may be absent or explicitly set to
undefined. Equivalent tooptionalKey(UndefinedOr(S)).Use
optionalKey
instead if you want exact optional semantics (absent only, not
undefined).Example (Defining an optional field accepting undefined)
import { Schema } from "effect"const schema = Schema.Struct({name: Schema.String,age: Schema.optional(Schema.Number)})// { readonly name: string; readonly age?: number | undefined }type Person = typeof schema.TypeSchema.import SchemaString),const String: Schema.StringType-level representation of
String
.
Schema for
stringvalues. Validates that the input istypeof"string".attendees:attendees: Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>Schema.import Schemaoptional(const optional: optionalLambda<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>(self: Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>) => Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>Type-level representation returned by
optional
.
Marks a struct field as optional, allowing the key to be absent or
undefined.Details
The resulting property may be absent or explicitly set to
undefined. Equivalent tooptionalKey(UndefinedOr(S)).Use
optionalKey
instead if you want exact optional semantics (absent only, not
undefined).Example (Defining an optional field accepting undefined)
import { Schema } from "effect"const schema = Schema.Struct({name: Schema.String,age: Schema.optional(Schema.Number)})// { readonly name: string; readonly age?: number | undefined }type Person = typeof schema.TypeSchema.import SchemaArray(Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>(self: Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>): Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>export ArrayDefines a
ReadonlyArrayschema for a given element schema.Example (Defining an array of strings)
import { Schema } from "effect"const schema = Schema.Array(Schema.String)Schema.decodeUnknownSync(schema)(["a", "b", "c"]) // => ["a", "b", "c"]Ref.import RefRef(const Ref: <typeof Person>(type: typeof Person) => Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown> (+3 overloads)Person))),class Person}).pipe(Pipeable.pipe<Schema.Struct<{readonly title: Schema.String;readonly description: Schema.optional<Schema.String>;readonly attendees: Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>;}>, Schema.Struct<{readonly title: Schema.String;readonly description: Schema.optional<Schema.String>;readonly attendees: Schema.optional<Schema.$Array<Ref.RefSchema<Person & OfKind<EntityKind.Object> & Unknown>>>;}>, Schema.Struct<...>>(this: Schema.Struct<...>, ab: (_: Schema.Struct<...>) => Schema.Struct<...>, bc: (_: Schema.Struct<...>) => Schema.Struct<...>): Schema.Struct<...> (+21 overloads)Annotation.import AnnotationIconAnnotation.const IconAnnotation: Annotation.Annotation<Annotation.IconAnnotation>export IconAnnotationIcon to render in the UI.
set({Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <S extends Schema.Top>(schema: S) => SSet the annotation on an Effect schema.
Only accepts
Schema.Top— annotations must be applied to the source schema BEFORE wrapping it withType.makeObject/Type.makeRelation. In a pipe, place everyAnnotation.X.set(...)before theType.make...step.icon: 'ph--calendar-dots--regular',icon: stringSprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').
ph--*is Phosphor;px--*anddx--*are brand glyphs, which are sprite-only and carry no weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic session, a GitHub repo — has no honest Phosphor equivalent.hue: 'green' }),hue?: string | undefinedColor name.
List of colors:
- 'red'
- 'orange'
- 'amber'
- 'yellow'
- 'lime'
- 'green'
- 'emerald'
- 'teal'
- 'cyan'
- 'violet'
- 'purple'
- 'fuchsia'
- 'pink'
- 'rose'
Annotation.import AnnotationLabelAnnotation.const LabelAnnotation: AnnotationHelper<string[]>export LabelAnnotationset(['title']),AnnotationHelper<string[]>.set: (value: string[]) => <S extends Schema.Top>(schema: S) => SSet the annotation on an Effect schema.
Only accepts
Schema.Top— annotations must be applied to the source schema BEFORE wrapping it withType.makeObject/Type.makeRelation. In a pipe, place everyAnnotation.X.set(...)before theType.make...step.),) {} -
List the types. The client is given this list when the app starts, in Installation.
export consttypes = [const types: (typeof Organization | typeof Person | typeof Event)[]Organization,class OrganizationPerson,class PersonEvent];class Event -
Create instances.
Obj.maketakes the props the schema allows, andRef.makemakes a reference to an object.constnorthwind =const northwind: Obj.OfShape<Organization & OfKind<EntityKind.Object>>Obj.import Objmake(function make<typeof Organization>(type: typeof Organization, props: NoInfer<Obj.MakeProps<typeof Organization>>, options?: Obj.MakeOptions): Obj.OfShape<Organization & OfKind<EntityKind.Object>>Creates a new echo object of the given schema or
Type.Type.Organization, {class Organizationname: 'Northwind Labs',name: stringwebsite: 'https://northwind.example' });website?: string | undefinedconstada =const ada: Obj.OfShape<Person & OfKind<EntityKind.Object>>Obj.import Objmake(function make<typeof Person>(type: typeof Person, props: NoInfer<Obj.MakeProps<typeof Person>>, options?: Obj.MakeOptions): Obj.OfShape<Person & OfKind<EntityKind.Object>>Creates a new echo object of the given schema or
Type.Type.Person, {class Personname: 'Ada Lovelace',name: stringemployer:employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefinedRef.import Refmake(const make: <Obj.OfShape<Organization & OfKind<EntityKind.Object>>>(object: Obj.OfShape<Organization & OfKind<EntityKind.Object>>) => Ref<Obj.OfShape<Organization & OfKind<EntityKind.Object>>>Create a reference to an entity.
northwind) });const northwind: Obj.OfShape<Organization & OfKind<EntityKind.Object>>constreview =const review: Obj.OfShape<Event & OfKind<EntityKind.Object>>Obj.import Objmake(function make<typeof Event>(type: typeof Event, props: NoInfer<Obj.MakeProps<typeof Event>>, options?: Obj.MakeOptions): Obj.OfShape<Event & OfKind<EntityKind.Object>>Creates a new echo object of the given schema or
Type.Type.Event, {class Eventtitle: 'Quarterly review',title: stringattendees: [attendees?: readonly Ref<Person & OfKind<EntityKind.Object> & Obj.Unknown>[] | undefinedRef.import Refmake(const make: <Obj.OfShape<Person & OfKind<EntityKind.Object>>>(object: Obj.OfShape<Person & OfKind<EntityKind.Object>>) => Ref<Obj.OfShape<Person & OfKind<EntityKind.Object>>>Create a reference to an entity.
ada)] });const ada: Obj.OfShape<Person & OfKind<EntityKind.Object>>Leave out a person’s
nameand the compiler rejects the call. -
Follow a reference.
peekreads the target, if it is loaded, without waiting.// The reference holds the organization's identity, not a copy of it.constemployer =const employer: (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefinedada.const ada: Obj.OfShape<Person & OfKind<EntityKind.Object>>employer?.employer?: Ref<Organization & OfKind<EntityKind.Object> & Obj.Unknown> | undefinedpeek();Ref<Organization & OfKind<EntityKind.Object> & Unknown>.peek(): (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefinedconsole.var console: ConsoleThe
consolemodule provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.The module exports two specific components:
- A
Consoleclass with methods such asconsole.log(),console.error()andconsole.warn()that can be used to write to any Node.js stream. - A global
consoleinstance configured to write toprocess.stdoutandprocess.stderr. The globalconsolecan be used without importing thenode:consolemodule.
Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the
note on process I/Ofor more information.Example using the global
console:console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderrExample using the
Consoleclass:const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err);myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to errconst name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to errlog(Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)Prints to
stdoutwith newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar toprintf(3)(the arguments are all passed toutil.format()).const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdoutSee
util.format()for more information.employer?.const employer: (Organization & OfKind<EntityKind.Object> & Obj.Unknown) | undefinedname);name: string | undefined - A
Try it
Section titled “Try it”The form beside the list is built from the selected type’s schema: a URL field for a website, a picker of organizations for an employer, and a list of people for an event’s attendees. Choose a type to see its form, or a record to see its values. Editing comes on the next page.
What you can do now
Section titled “What you can do now”You can declare object types with references between them, give a type an icon and a label, and create objects that the compiler checks against their schema.
Mutating objects: add, change and remove the app’s records.