TypeScript types
A component that reads PAD's data - the props of an island, the JSON of a page - knows its shape only from what the PHP happens to make. pad types writes that shape down as TypeScript, made from the data itself:
pad types shop orders # to standard output
pad types shop orders --out=www/shop/src/types/pad.d.ts
-
OrdersVars- the variables of the page's PHP, read from its sample (_samples/orders.json, see Samples); a page without a sample gets one captured first. -
OrdersAnswer- the JSON the page answers withpadFormat=json, what its$padExposenames (Data answers), when it answers one. - Without pages, every page that has a sample. The types are only as good as the sample: a list that was empty is
unknown[], a value that wasnullisnull- capture the page with data that shows every field.
How a value becomes a type:
|
PHP fragments/typescript_types_1.php |
HTML fragments/typescript_types_1.pad |
Result |
|---|---|---|
|
|
export interface OrdersVars {
orders: {
id: number;
total: number;
customer: {
name: string;
};
gift?: boolean;
}[];
note: null;
}
|
A list of rows is one row type - a key some rows lack is optional (gift?), a key whose rows disagree gets a union - and other lists are a union of their items. A component then types its props from the declarations, and tsc --noEmit fails on a field the PHP does not have:
import type { OrdersVars } from './types/pad';
type Order = OrdersVars['orders'][number];
export default function OrderRow(order: Order) { ... }
The islands application types one island this way (examples/typed), its npm run types and npm run check doing both steps.