SpecSheriff
rule · _guidelines/tools/17 · s-suv42g8r3ra2h6b

What a data record node generates

Checkedconfirmed by its owner

From each data record node, sheriff types writes a type into each file of types and a definition under $defs into each file of runtime checks. It takes the nodes in the order the specification reads: its files in the code-point order of their paths, and the nodes of each file in the order they stand.

Every type and definition is named by the data record's name with the first letter of each word raised and the spaces dropped. Each type is tagged with the sid of its data record, as a symbol of code is tagged with the rule it implements (§s-5z5gnu7pahr82xp).

A type and a definition hold the fields of every data record above the node along its refines links, the topmost first, then the node's own fields, except a variant's own, which stand where the rule on data record variants places them (§s-nk8td3ez58gahc4); each field keeps its name and the order its node gives it, and is required where its node says so and optional otherwise. A field of type record refers to the type of that data record by its name, and the object of a field of type variant is written out in full. Where the data record node refuses a field nobody declared, its definition refuses any property its fields do not declare.

A name that is not an identifier in the language of its file, or that the file already uses — the names it imports and those its language builds in included — cannot be generated.

In TypeScript a type is written export type <name> = {...}.

In Python a type is written <name> = TypedDict("<name>", {...}), every name it uses imported from typing, a reference to another type written as a string, an optional field marked NotRequired, and the object of a field of type variant given a type of its own, named by the type it stands in followed by the field's name with its first letter raised, and tagged with the same sid.

Why

One name in every file lets a reader follow a data record from its node to each copy, and a fixed order makes each file come out the same at every run, which the comparison of generated copies needs. The generator writes the tag itself, so that the link from each type to its node is made anew with the type and never kept by hand.

A data record that refines another holds that one's fields, as the schema of the nodes says, and a field keeps the name its node gives because the code uses that name as it stands. Only a runtime check can refuse an undeclared property; a type in TypeScript or Python cannot.

A name the file already uses would break its compilation or hide what it imports.

The functional form of TypedDict takes any field name, a keyword of Python included; a reference written as a string may name a type written later in the file, or the type itself; and Python can name the object of a field only by a type of its own.

The links it makes

The links made to it

The tests bound to it