Typed tables
matter app types writes matter-app.d.ts, or the path that types in matter.json names. It holds the SDK’s types, plus one entry for each table in the app’s space, generated from the tables as they are in Matter now. Include it in your tsconfig.json.
matter.table('Deals') is then typed, and the compiler catches what the data API would refuse at run time:
- a table, index or field that doesn’t exist;
- an
eqthat’s missing one of the index’s match fields, or names an option the field doesn’t have; - a
rangeon anything but the index’s first order field, or with the wrong type of value; - a
sortorfilteron a field that doesn’t exist; groupCountby a field that isn’t one of the index’s match fields;upserton an index that isn’t unique;- write values of the wrong type, or several people for a field that holds one.
Rows come back typed. row.values.Stage is 'Lead' | 'Won' | …, and fields that may be empty are optional. Option names in row values also accept any string, since someone may add an option in Matter after you generated the types. Writes, eq and filters accept only the options the field has, unless a write passes { createOptions: true } to add the ones it names (see Options).
Without generated types, every table is untyped.
Keeping them current
Section titled “Keeping them current”matter app devregenerates the file whenever the space’s tables change while it runs, so a field added in Matter is in your types seconds later.matter app deploywarns when the file is out of date.- Otherwise, run
matter app typesagain after changing tables or updating Matter.
Don’t edit the file: it’s rewritten each time.
In your own helpers
Section titled “In your own helpers”The types export what you need to write typed helpers, such as React hooks:
| Type | What it is |
|---|---|
Tables |
Every table of the space, by name. |
TableRead<T> |
Any read of a table: through one of its indexes, with that index’s own checks, or a scan. |
TableMatch<T> |
Rows matching any of a table’s indexes, for count, exists and ids. |
TableGroupRead<T> |
A groupCount through any of a table’s indexes. |
TypedGroups<T, I> |
What groupCount gives through index I. |
Row<Values> |
A row with these values. |
Person, LinkedRow, Attachment |
The shapes of those values. |
import type { Row, TableRead, Tables } from '/_matter/sdk.js'
type TableName = keyof Tables & stringdeclare function useQuery<N extends TableName>( table: N, read: TableRead<Tables[N]> | null,): Row<Tables[N]['values']>[]
const LEADS: TableRead<Tables['Deals']> = { index: 'by_stage', eq: { Stage: 'Lead' } }In Node
Section titled “In Node”In a worker or tools written in TypeScript, type the module with the same file:
const { default: matter } = (await import(process.env.MATTER_SDK!)) as typeof import('@matter/app-sdk')