Skip to Content

typia.protobuf.*Decode โ€” Protocol Buffer bytes โ†’ TypeScript object

signatures
namespace protobuf { function decode<T>(buffer: Uint8Array): Resolved<T>; function isDecode<T>(buffer: Uint8Array): Resolved<T> | null; function assertDecode<T>(buffer: Uint8Array): Resolved<T>; function validateDecode<T>(buffer: Uint8Array): IValidation<Resolved<T>>; }

The decoder reads T at compile time and emits a hand-rolled binary reader for that shape โ€” same model as the encoder, in reverse.

First example

hello-decode.ts
import typia from "typia"; interface User { id: string; age: number; hobbies: string[] } const bytes: Uint8Array = await fetchBytesSomehow(); const user = typia.protobuf.assertDecode<User>(bytes); // โ†’ User, with type tag constraints validated. Throws on mismatch.
examples/src/protobuf/decode.ts
import typia, { tags } from "typia"; const member: IMember = typia.random<IMember>(); const encoded: Uint8Array = typia.protobuf.encode<IMember>(member); const decoded: IMember = typia.protobuf.decode<IMember>(encoded); console.log(member, decoded); interface IMember { id: | (string & tags.Sequence<11>) | (number & tags.Type<"uint64"> & tags.Sequence<12>) | (Uint8Array & tags.Sequence<13>); name: (string & tags.Sequence<20>) | null; children: Array<IMember> & tags.Sequence<30>; keywords: Map<string, string> & tags.Sequence<40>; thumbnail: | (string & tags.Format<"uri"> & tags.ContentMediaType<"image/*">) | Uint8Array; email: string & tags.Format<"email">; hobbies: Array<IHobby>; } interface IHobby { id: string & tags.Format<"uuid">; name: string; valid: boolean; }

Variants

FunctionValidates result?On failure
protobuf.decode<T>Nooutput is whatever fell out of the binary reader
protobuf.isDecode<T>Yes (is)returns null
protobuf.assertDecode<T>Yes (assert)throws TypeGuardError
protobuf.validateDecode<T>Yes (validate)returns IValidation<Resolved<T>>
Important

What the *Decode validators actually verify.

They check custom tag constraints โ€” tags.Format<"uuid">, tags.Minimum<0>, etc. They do not re-verify that the bytes were structurally valid Protocol Buffer for T โ€” the decoder already did that decoding work. So you can rely on these to catch โ€œthe producer encoded a UUID thatโ€™s actually not a UUIDโ€ but not โ€œsomeone fed me random bytes.โ€

The safe pattern is: producer uses protobuf.assertEncode (or validateEncode), consumer uses protobuf.assertDecode (or validateDecode). Then both ends of the wire are checked.

undefined

export namespace protobuf { export function decode<T>(buffer: Uint8Array): Resolved<T>; export function isDecode<T>(buffer: Uint8Array): Resolved<T> | null; export function assertDecode<T>(buffer: Uint8Array): Resolved<T>; export function validateDecode<T>( buffer: Uint8Array, ): IValidation<Resolved<T>>; }

Reusable factories

const decodeUser = typia.protobuf.createAssertDecode<User>();
examples/src/protobuf/createDecode.ts
import typia, { tags } from "typia"; export const decode = typia.protobuf.createDecode<IMember>(); interface IMember { id: | (string & tags.Sequence<11>) | (number & tags.Type<"uint64"> & tags.Sequence<12>) | (Uint8Array & tags.Sequence<13>); name: (string & tags.Sequence<20>) | null; children: Array<IMember> & tags.Sequence<30>; keywords: Map<string, string> & tags.Sequence<40>; thumbnail: | (string & tags.Format<"uri"> & tags.ContentMediaType<"image/*">) | Uint8Array; email: string & tags.Format<"email">; hobbies: Array<IHobby>; } interface IHobby { id: string & tags.Format<"uuid">; name: string; valid: boolean; }

Restrictions

Same as the rest of the protobuf surface โ€” see protobuf.message.

Where to go next

Last updated on