Types

Introduction

When using the Block Protocol's graph module, data is shared between applications and blocks in the form of 'entities', and each entity has a type, known as an 'entity type'.

This type describes what properties an entity has, what type of value each is expected to be, and the relationship between the entity in question and other entities.

Relationships between entities are known as 'links' and they too are entities, which means they may have properties and relations to other entities.

The system by which types are defined is known as the 'type system'.

The type system

The Block Protocol's type system is designed so that types are composed of re-usable, sharable parts, which can be referenced by other users and by other types.

The type system consists of three classes of elements:

  1. Entity types: define what properties an entity may have (which property types), and what relationships (links) it may have with other entities
  2. Property types: define properties that can be referenced by entity types, and their expected values, which may be a reference to data types or objects which are made up of other property types
  3. Data types: primitive data types, e.g. text, numbers, booleans.

Creating types

The easiest way to get started is to visit your dashboard and click 'create an entity type'.

Give your entity type a name and a description, and then click 'create'.

You can now define the properties your entity expects:

  1. Start typing to see if a suitable property already exists (e.g. called 'Name' with an expected data type of 'Text')
  2. Either select an existing property type, or click 'create new' to create a new one
  3. If creating a new one, specify a title, description, and expected value

A basic entity type with a Name property

You can also define the links your entity expects following a similar process:

  1. Start typing to see if a suitable link entity type already exists (e.g. called 'Owner')
  2. Either select an existing link entity type, or click 'create new' to create a new one
  3. When creating a link entity type, you first specify a title and description
  4. Back on your initial entity type, you can select the link entity type as a potential link from your entity, and then constrain the destination entities of those links by defining a selection of entity types. You can also set a minimum number of such links (e.g. to make it so that entities of your type are required to have certain links).

Make sure to click 'publish update' when you're done to release a new version of the entity type.

Using types

Once you have a type which describes the data your block expects, copy the URL from your browser.

  • for blocks from the html template, you can use this as the schema property in the block-metadata.json
  • for blocks made from the react and custom-element template, you can use this for the blockEntityType property in the blockprotocol object in package.json or as an input for codegen (see below)

You can also view the raw JSON of any type by a simple fetch or curl:

fetch("https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2")
  .then((resp) => resp.json())
  .then(console.log);
curl https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2

TypeScript types for entities

Types within the Type System are representable within TypeScript, and as such it is possible to create TypeScript representations of entity types. There is a provided codegen utility in the @blockprotocol/graph package which provides an implementation of such generation. For relatively simple cases, a wrapper around this is exposed through block-scripts which is able to parse the metadata about your block and generate types for you. An example usage of this is included within the react and custom-element block templates.

For react and custom-element blocks, the codegen object in package.json can be used to configure block-scripts codegen. This is setup by default within the templates, and can be ran with yarn codegen.

The codegen object has the following:

  • a field outputFolder which describes the folder which will contain the files with the generated types
    • all contents of this folder are deleted when the codegen is run
  • a field targets which is an object which is a mapping of files to the types that should be generated within them
    • keys of targets are the names of the files to be generated (e.g. person.ts)
    • values of targets are an array where the items are objects which satisfy the following:
      • contain the key sourceTypeId with a value of an ID of a type in the Type System (e.g. https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2), or
      • contain the key blockEntityType with value true, which if present will generate types for the type given by the blockEntityType property in the blockprotocol object in package.json, alongside type aliases for it such as BlockEntity
        • there can be one at most of these entries in the whole of the codegen object

For example:

{
  "blockprotocol": {
    // ...
    "blockEntityType": "https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2",
    "codegen": {
      "outputFolder": "src/types/generated",
      "targets": {
        "block-entity.ts": [
          {
            // generate types in `block-entity.ts` for `Thing` (specified above) as this block's `BlockEntity`
            "blockEntityType": true
          },
          {
            // generate types in `block-entity.ts` for `Person`
            "sourceTypeId": "https://blockprotocol.org/@example/types/entity-type/person/v/3"
          }
        ],
        "company.ts": [
          {
            // generate types in `company.ts` for `Company`
            "sourceTypeId": "https://blockprotocol.org/@example/types/entity-type/company/v/1"
          }
        ]
      }
    }
  }
}