shield()
Environment: server.
We use shield()
to guarantee the type of telefunction arguments. (As explained in Overview > RPC,
telefunctions are public and need protection.)
If we use TypeScript, then Telefunc automaticaly defines
shield()
, see TypeScript - Automatic.
TypeScript - Automatic
If we use TypeScript, then Telefunc automatically generates shield()
for each telefunction.
In other words: telefunction argument types are automatically validated at runtime:
With Telefunc, not only can we seamlessly re-use types across our frontend and backend code, but we also get automatic type-safety at runtime. If we use a TypeScript ORM (e.g. Prisma) or SQL builder (e.g. Kysely and others), then we get end-to-end type safety all the way from database to frontend.
For a faster development, Telefunc doesn't generate
shield()
and your telefunction arguments aren't validated during development. Telefunc only generatesshield()
upon building your app for production. You can enable the generation ofshield()
for development by settingconfig.shield.dev
totrue
.
Telefunc's automatic
shield()
generation only works for stacks that transpile server-side code (Next.js, Vite, Vike, SvelteKit, Nuxt, etc.).For stacks that don't transpile server-side code (e.g. React Native, CRA, Parcel), we need to define
shield()
manually ourselves: see TypeScript - Manual.
TypeScript - Manual
If we define shield()
manually (instead of using Telefunc's automatic shield()
generator as described in TypeScript - Automatic), then note that we don't need to define the arguments type twice:
Note that the following doesn't work:
Common types
Examples showcasing the most common shield()
types:
All types
List of shield()
types:
const t = shield.type | TypeScript | JavaScript |
---|---|---|
t.string | string | typeof value === 'string' |
t.number | number | typeof value === 'number' |
t.boolean | boolean | value === true || value === false |
t.date | Date | value.constructor === Date |
t.array(T) | T[] | value.every(element => isT(element)) |
t.object(T) | Record<string, T> | Object.values(value).every(v => isT(v)) |
{ k1: T1, k2: T2, ... } | { k1: T1, k2: T2, ... } | isT1(value.k1) && isT2(value.k2) && ... |
t.or(T1, T2, ...) | T1 | T2 | ... | isT1(value) || isT2(value) || ... |
t.tuple(T1, T2, ...) | [T1, T2, ...] | isT1(value[0]) && isT2(value[1]) && ... |
t.const(val) | val as const | value === val |
t.optional(T) | T | undefined | isT(value) || value === undefined |
t.nullable(T) | T | null | isT(value) || value === null |
t.any | any | true |