Object types and links can contain properties: a name-value collection of primitive data associated with the given object or link instance.

Every property is declared to have a specific scalar type or a collection type based on a scalar.

There are two kinds of property item declarations: abstract properties, and concrete properties. Abstract properties are defined on the module level and are not tied to any particular object type or link. Typically this is done to set some annotations, or define constraints. Concrete properties are defined on specific object types.

Similar to links, properties have a source (the object type or link on which they are defined) and one or more targets (the values that property can have).

Properties defined on object types have the number of targets specified by the keywords required, single, and multi. It is also possible to restrict how many source objects can have the same property value via the exclusive constraint. For the purpose of figuring out the number of property targets, a collection type target by itself is considered a single target.

For example, here’s an object type with a single required exclusive property name and an optional multi property favorite_tags:

type Person {
    required property name -> str {
        constraint exclusive;
    multi property favorite_tags -> str;

Since the empty string '' is a value, required properties can take on '' as their value.

Propery SDL, DDL, and introspection (as part of overall object introspection).