typia.protobuf.*Decode โ Protocol Buffer bytes โ TypeScript object
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
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.TypeScript Source
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;
}Compiled JavaScript
/* @ttsc-rewritten */
const {
_isFormatEmail: __typia_transform__isFormatEmail,
} = require("typia/lib/internal/_isFormatEmail");
const {
_isFormatUri: __typia_transform__isFormatUri,
} = require("typia/lib/internal/_isFormatUri");
const {
_isFormatUuid: __typia_transform__isFormatUuid,
} = require("typia/lib/internal/_isFormatUuid");
const {
_isTypeUint64: __typia_transform__isTypeUint64,
} = require("typia/lib/internal/_isTypeUint64");
const {
_randomFormatEmail: __typia_transform__randomFormatEmail,
} = require("typia/lib/internal/_randomFormatEmail");
const {
_randomFormatUri: __typia_transform__randomFormatUri,
} = require("typia/lib/internal/_randomFormatUri");
const {
_randomFormatUuid: __typia_transform__randomFormatUuid,
} = require("typia/lib/internal/_randomFormatUuid");
const {
_randomString: __typia_transform__randomString,
} = require("typia/lib/internal/_randomString");
const {
_randomInteger: __typia_transform__randomInteger,
} = require("typia/lib/internal/_randomInteger");
const {
_randomArray: __typia_transform__randomArray,
} = require("typia/lib/internal/_randomArray");
const {
_randomBoolean: __typia_transform__randomBoolean,
} = require("typia/lib/internal/_randomBoolean");
const {
_randomPick: __typia_transform__randomPick,
} = require("typia/lib/internal/_randomPick");
const {
_ProtobufReader: __typia_transform__ProtobufReader,
} = require("typia/lib/internal/_ProtobufReader");
const {
_ProtobufSizer: __typia_transform__ProtobufSizer,
} = require("typia/lib/internal/_ProtobufSizer");
const {
_ProtobufWriter: __typia_transform__ProtobufWriter,
} = require("typia/lib/internal/_ProtobufWriter");
const {
_throwTypeGuardError: __typia_transform__throwTypeGuardError,
} = require("typia/lib/internal/_throwTypeGuardError");
const member = (() => {
const _ro0 = (_recursive = true, _depth = 0) => ({
id: __typia_transform__randomPick([
() =>
(_generator?.string ?? __typia_transform__randomString)({
type: "string",
"x-protobuf-sequence": 11,
}),
() =>
(_generator?.integer ?? __typia_transform__randomInteger)({
type: "integer",
minimum: 0,
"x-protobuf-sequence": 12,
}),
() =>
new Uint8Array(
5 >= _depth
? (_generator?.array ?? __typia_transform__randomArray)({
type: "array",
element: () =>
(_generator?.integer ?? __typia_transform__randomInteger)({
type: "integer",
minimum: 0,
maximum: 255,
}),
})
: [],
),
])(),
name: __typia_transform__randomPick([
() => null,
() =>
(_generator?.string ?? __typia_transform__randomString)({
type: "string",
"x-protobuf-sequence": 20,
}),
])(),
children:
5 >= _depth
? (_generator?.array ?? __typia_transform__randomArray)({
type: "array",
"x-protobuf-sequence": 30,
element: () => _ro0(true, _recursive ? 1 + _depth : _depth),
})
: [],
keywords: new Map(
5 >= _depth
? (_generator?.array ?? __typia_transform__randomArray)({
type: "array",
element: () => [
(_generator?.string ?? __typia_transform__randomString)({
type: "string",
}),
(_generator?.string ?? __typia_transform__randomString)({
type: "string",
}),
],
})
: [],
),
thumbnail: __typia_transform__randomPick([
() => (_generator?.uri ?? __typia_transform__randomFormatUri)(),
() =>
new Uint8Array(
5 >= _depth
? (_generator?.array ?? __typia_transform__randomArray)({
type: "array",
element: () =>
(_generator?.integer ?? __typia_transform__randomInteger)({
type: "integer",
minimum: 0,
maximum: 255,
}),
})
: [],
),
])(),
email: (_generator?.email ?? __typia_transform__randomFormatEmail)(),
hobbies:
5 >= _depth
? (_generator?.array ?? __typia_transform__randomArray)({
type: "array",
element: () => _ro1(true, _recursive ? 1 + _depth : _depth),
})
: [],
});
const _ro1 = (_recursive = false, _depth = 0) => ({
id: (_generator?.uuid ?? __typia_transform__randomFormatUuid)(),
name: (_generator?.string ?? __typia_transform__randomString)({
type: "string",
}),
valid: (_generator?.boolean ?? __typia_transform__randomBoolean)(),
});
let _generator;
return (generator) => {
_generator = generator;
return _ro0();
};
})()();
const encoded = (() => {
const encoder = (writer, input) => {
const _peo0 = (input) => {
// property "id": ((Uint8Array & Sequence<13>) | (number & Type<"uint64"> & Sequence<12>) | (string & Sequence<11>));
if (input.id instanceof Uint8Array) {
writer.uint32(10);
writer.bytes(input.id);
} else if ("number" === typeof input.id) {
writer.uint32(16);
writer.uint64(input.id);
} else if ("string" === typeof input.id) {
writer.uint32(26);
writer.string(input.id);
} else
__typia_transform__throwTypeGuardError({
method: "encode",
expected:
'((Uint8Array & Sequence<13>) | (number & Type<"uint64"> & Sequence<12>) | (string & Sequence<11>))',
value: input.id,
});
// property "name": ((string & Sequence<20>) | null);
if (null !== input.name) {
writer.uint32(34);
writer.string(input.name);
}
// property "children": (Array<IMember> & Sequence<30>);
if (0 !== input.children.length) {
for (const elem of input.children) {
writer.uint32(42);
writer.fork();
_peo0(elem);
writer.ldelim();
}
}
// property "keywords": Map<string, string>;
for (const [key, value] of input.keywords) {
writer.uint32(50);
writer.fork();
writer.uint32(10);
writer.string(key);
writer.uint32(18);
writer.string(value);
writer.ldelim();
}
// property "thumbnail": ((string & Format<"uri"> & ContentMediaType<"image/*">) | Uint8Array);
if (input.thumbnail instanceof Uint8Array) {
writer.uint32(58);
writer.bytes(input.thumbnail);
} else if ("string" === typeof input.thumbnail) {
writer.uint32(66);
writer.string(input.thumbnail);
} else
__typia_transform__throwTypeGuardError({
method: "encode",
expected:
'((string & Format<"uri"> & ContentMediaType<"image/*">) | Uint8Array)',
value: input.thumbnail,
});
// property "email": (string & Format<"email">);
writer.uint32(74);
writer.string(input.email);
// property "hobbies": Array<IHobby>;
if (0 !== input.hobbies.length) {
for (const elem of input.hobbies) {
writer.uint32(82);
writer.fork();
_peo1(elem);
writer.ldelim();
}
}
};
const _peo1 = (input) => {
// property "id": (string & Format<"uuid">);
writer.uint32(10);
writer.string(input.id);
// property "name": string;
writer.uint32(18);
writer.string(input.name);
// property "valid": boolean;
writer.uint32(24);
writer.bool(input.valid);
};
const _io0 = (input) =>
null !== input.id &&
undefined !== input.id &&
("string" === typeof input.id ||
("number" === typeof input.id &&
__typia_transform__isTypeUint64(input.id)) ||
input.id instanceof Uint8Array) &&
(null === input.name || "string" === typeof input.name) &&
Array.isArray(input.children) &&
input.children.every(
(elem) => "object" === typeof elem && null !== elem && _io0(elem),
) &&
input.keywords instanceof Map &&
(() =>
[...input.keywords].every(
(elem) =>
Array.isArray(elem) &&
elem.length === 2 &&
"string" === typeof elem[0] &&
"string" === typeof elem[1],
))() &&
null !== input.thumbnail &&
undefined !== input.thumbnail &&
(("string" === typeof input.thumbnail &&
__typia_transform__isFormatUri(input.thumbnail)) ||
input.thumbnail instanceof Uint8Array) &&
"string" === typeof input.email &&
__typia_transform__isFormatEmail(input.email) &&
Array.isArray(input.hobbies) &&
input.hobbies.every(
(elem) => "object" === typeof elem && null !== elem && _io1(elem),
);
const _io1 = (input) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid(input.id) &&
"string" === typeof input.name &&
"boolean" === typeof input.valid;
_peo0(input);
return writer;
};
return (input) => {
const sizer = encoder(new __typia_transform__ProtobufSizer(), input);
const writer = encoder(new __typia_transform__ProtobufWriter(sizer), input);
return writer.buffer();
};
})()(member);
const decoded = (() => {
const _pdo0 = (reader, length = -1) => {
length = length < 0 ? reader.size() : reader.index() + length;
const output = {
id: new Uint8Array([]),
name: null,
children: [],
keywords: new Map(),
thumbnail: new Uint8Array([]),
email: "",
hobbies: [],
};
while (reader.index() < length) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
// bytes;
output.id = reader.bytes();
break;
case 2:
// uint64;
output.id = Number(reader.uint64());
break;
case 3:
// string;
output.id = reader.string();
break;
case 4:
// string;
output.name = reader.string();
break;
case 5:
// Array<IMember>;
output.children.push(_pdo0(reader, reader.uint32()));
break;
case 6:
// Map<string, string>;
(() => {
output.keywords ??= new Map();
const piece = reader.uint32() + reader.index();
const entry = {
key: "",
value: "",
};
while (reader.index() < piece) {
const kind = reader.uint32();
switch (kind >>> 3) {
case 1:
// string;
entry.key = reader.string();
break;
case 2:
// string;
entry.value = reader.string();
break;
default:
reader.skipType(kind & 7);
break;
}
}
output.keywords.set(entry.key, entry.value);
})();
break;
case 7:
// bytes;
output.thumbnail = reader.bytes();
break;
case 8:
// string;
output.thumbnail = reader.string();
break;
case 9:
// string;
output.email = reader.string();
break;
case 10:
// Array<IHobby>;
output.hobbies.push(_pdo1(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return output;
};
const _pdo1 = (reader, length = -1) => {
length = length < 0 ? reader.size() : reader.index() + length;
const output = {
id: "",
name: "",
valid: undefined,
};
while (reader.index() < length) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
// string;
output.id = reader.string();
break;
case 2:
// string;
output.name = reader.string();
break;
case 3:
// bool;
output.valid = reader.bool();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return output;
};
return (input) => {
const reader = new __typia_transform__ProtobufReader(input);
return _pdo0(reader);
};
})()(encoded);
console.log(member, decoded);Variants
| Function | Validates result? | On failure |
|---|---|---|
protobuf.decode<T> | No | output 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>> |
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>>;
}undefined
/**
* Validation result type with detailed error information.
*
* `IValidation<T>` is the return type of `typia.validate<T>()` and related
* validation functions. Unlike `typia.is<T>()` which returns a boolean, or
* `typia.assert<T>()` which throws exceptions, `typia.validate<T>()` returns
* this structured result with full error details.
*
* Check the {@link IValidation.success | success} discriminator:
*
* - `true` โ {@link IValidation.ISuccess} with validated
* {@link IValidation.ISuccess.data | data}
* - `false` โ {@link IValidation.IFailure} with
* {@link IValidation.IFailure.errors | errors} array
*
* This is the recommended validation function when you need to report
* validation errors to users or log them for debugging.
*
* @author Jeongho Nam - https://github.com/samchon
* @example
* const result = typia.validate<User>(input);
* if (result.success) {
* return result.data; // User type
* } else {
* result.errors.forEach((e) => console.log(e.path, e.expected));
* }
*
* @template T The expected type after successful validation
*/
export type IValidation<T = unknown> =
| IValidation.ISuccess<T>
| IValidation.IFailure;
export namespace IValidation {
/**
* Successful validation result.
*
* Indicates the input matches the expected type. The validated data is
* available in {@link data} with full type information.
*
* @template T The validated type
*/
export interface ISuccess<T = unknown> {
/**
* Success discriminator.
*
* Always `true` for successful validations. Use this to narrow the type
* before accessing {@link data}.
*/
success: true;
/**
* The validated data with correct type.
*
* The original input after successful validation. TypeScript will narrow
* this to type `T` when {@link success} is `true`.
*/
data: T;
}
/**
* Failed validation result with error details.
*
* Indicates the input did not match the expected type. Contains the original
* data and an array of all validation errors found.
*/
export interface IFailure {
/**
* Success discriminator.
*
* Always `false` for failed validations. Use this to narrow the type before
* accessing {@link errors}.
*/
success: false;
/**
* The original input that failed validation.
*
* Preserved as `unknown` type since it didn't match the expected type.
* Useful for debugging or logging the actual value.
*/
data: unknown;
/**
* Array of validation errors.
*
* Contains one entry for each validation failure found. Multiple errors may
* exist if the input has multiple type mismatches.
*/
errors: IError[];
}
/**
* Detailed information about a single validation error.
*
* Describes exactly what went wrong during validation, including the
* location, expected type, and actual value.
*/
export interface IError {
/**
* Property path to the error location.
*
* A dot-notation path from the root input to the failing property. Uses
* `$input` as the root. Example: `"$input.user.email"` or
* `"$input.items[0].price"`.
*/
path: string;
/**
* Expected type expression.
*
* A human-readable description of what type was expected at this location.
* Examples: `"string"`, `"number & ExclusiveMinimum<0>"`, `"(\"active\" |
* \"inactive\")"`.
*/
expected: string;
/**
* The actual value that failed validation.
*
* The value found at the error path. May be `undefined` if the property was
* missing. Useful for debugging type mismatches.
*/
value: unknown;
/**
* Human-readable error description.
*
* Optional additional context about the validation failure, such as
* constraint violations or custom error messages.
*/
description?: string;
}
}undefined
/**
* Error thrown when type assertion fails.
*
* Thrown by {@link assert}, {@link assertGuard}, and other assert-family
* functions when input doesn't match expected type `T`. Contains detailed
* information about the first assertion failure:
*
* - `method`: Which typia function threw (e.g., `"typia.assert"`)
* - `path`: Property path where error occurred (e.g., `"input.user.age"`)
* - `expected`: Expected type string (e.g., `"number & ExclusiveMinimum<19>"`)
* - `value`: Actual value that failed validation
*
* @template T Expected type (for type safety)
*/
export class TypeGuardError<T = any> extends Error {
/**
* Name of the typia method that threw this error.
*
* E.g., `"typia.assert"`, `"typia.assertEquals"`, `"typia.assertGuard"`.
*/
public readonly method: string;
/**
* Property path where assertion failed.
*
* Uses dot notation for nested properties. `undefined` if error occurred at
* root level.
*
* E.g., `"input.age"`, `"input.profile.email"`, `"input[0].name"`.
*/
public readonly path: string | undefined;
/**
* String representation of expected type.
*
* E.g., `"string"`, `"number & ExclusiveMinimum<19>"`, `"{ name: string; age:
* number }"`.
*/
public readonly expected: string;
/**
* Actual value that failed assertion.
*
* The raw value at the error path, useful for debugging.
*/
public readonly value: unknown;
/**
* Optional human-readable error description.
*
* Primarily for AI agent libraries or custom validation scenarios needing
* additional context. Standard assertions rely on `path`, `expected`, and
* `value` for error reporting.
*/
public readonly description?: string | undefined;
/**
* Phantom property for TypeScript type safety.
*
* Not used at runtimeโexists only to preserve generic type `T` in the type
* system. Always `undefined`.
*
* @internal
*/
protected readonly fake_expected_typed_value_?: T | undefined;
/**
* Creates a new TypeGuardError instance.
*
* @param props Error properties
*/
public constructor(props: TypeGuardError.IProps) {
// MESSAGE CONSTRUCTION
// Use custom message if provided, otherwise generate default format
super(
props.message ||
`Error on ${props.method}(): invalid type${
props.path ? ` on ${props.path}` : ""
}, expect to be ${props.expected}`,
);
// INHERITANCE POLYFILL
// Set up prototype for compatibility across different JavaScript environments
const proto = new.target.prototype;
if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto);
else (this as any).__proto__ = proto;
// ASSIGN MEMBERS
this.name = "TypeGuardError";
this.method = props.method;
this.path = props.path;
this.expected = props.expected;
this.value = props.value;
if (props.description || props.value === undefined)
this.description =
props.description ??
[
"The value at this path is `undefined`.",
"",
`Please fill the \`${props.expected}\` typed value next time.`,
].join("\n");
}
}
export namespace TypeGuardError {
/** Properties for constructing a TypeGuardError. */
export interface IProps {
/**
* Name of the typia method that threw the error.
*
* E.g., `"typia.assert"`, `"typia.assertEquals"`.
*/
method: string;
/**
* Property path where assertion failed (optional).
*
* E.g., `"input.age"`, `"input.profile.email"`.
*/
path?: undefined | string;
/**
* String representation of expected type.
*
* E.g., `"string"`, `"number & ExclusiveMinimum<19>"`.
*/
expected: string;
/** Actual value that failed assertion. */
value: unknown;
/**
* Optional human-readable error description.
*
* For AI agent libraries or custom validation needing additional context.
*/
description?: string;
/**
* Custom error message (optional).
*
* If not provided, a default message is generated from other properties.
*/
message?: undefined | string;
}
}undefined
import { Equal } from "./internal/Equal";
import { IsTuple } from "./internal/IsTuple";
import { NativeClass } from "./internal/NativeClass";
import { ValueOf } from "./internal/ValueOf";
/**
* Converts a type to its resolved form by erasing all methods.
*
* `Resolved<T>` transforms classes to plain objects, extracts primitive values
* from boxed types (Booleanโboolean, Numberโnumber, Stringโstring), and
* recursively processes nested structures. Native classes (Date, Set, Map,
* etc.) are preserved unchanged.
*
* @author Jeongho Nam - https://github.com/samchon
* @author Kyungsu Kang - https://github.com/kakasoo
* @template T Target type to resolve
*/
export type Resolved<T> =
Equal<T, ResolvedMain<T>> extends true ? T : ResolvedMain<T>;
type ResolvedMain<T> = T extends [never]
? never // (special trick for jsonable | null) type
: ValueOf<T> extends boolean | number | bigint | string
? ValueOf<T>
: T extends Function
? never
: T extends object
? ResolvedObject<T>
: ValueOf<T>;
type ResolvedObject<T extends object> =
T extends Array<infer U>
? IsTuple<T> extends true
? ResolvedTuple<T>
: ResolvedMain<U>[]
: T extends Set<infer U>
? Set<ResolvedMain<U>>
: T extends Map<infer K, infer V>
? Map<ResolvedMain<K>, ResolvedMain<V>>
: T extends WeakSet<any> | WeakMap<any, any>
? never
: T extends NativeClass
? T
: {
[P in keyof T]: ResolvedMain<T[P]>;
};
type ResolvedTuple<T extends readonly any[]> = T extends []
? []
: T extends [infer F]
? [ResolvedMain<F>]
: T extends [infer F, ...infer Rest extends readonly any[]]
? [ResolvedMain<F>, ...ResolvedTuple<Rest>]
: T extends [(infer F)?]
? [ResolvedMain<F>?]
: T extends [(infer F)?, ...infer Rest extends readonly any[]]
? [ResolvedMain<F>?, ...ResolvedTuple<Rest>]
: [];Reusable factories
const decodeUser = typia.protobuf.createAssertDecode<User>();TypeScript Source
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;
}Compiled JavaScript
import { _ProtobufReader as __typia_transform__ProtobufReader } from "typia/lib/internal/_ProtobufReader";
/* @ttsc-rewritten */
export const decode = (() => {
const _pdo0 = (reader, length = -1) => {
length = length < 0 ? reader.size() : reader.index() + length;
const output = {
id: new Uint8Array([]),
name: null,
children: [],
keywords: new Map(),
thumbnail: new Uint8Array([]),
email: "",
hobbies: [],
};
while (reader.index() < length) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
// bytes;
output.id = reader.bytes();
break;
case 2:
// uint64;
output.id = Number(reader.uint64());
break;
case 3:
// string;
output.id = reader.string();
break;
case 4:
// string;
output.name = reader.string();
break;
case 5:
// Array<IMember>;
output.children.push(_pdo0(reader, reader.uint32()));
break;
case 6:
// Map<string, string>;
(() => {
output.keywords ??= new Map();
const piece = reader.uint32() + reader.index();
const entry = {
key: "",
value: "",
};
while (reader.index() < piece) {
const kind = reader.uint32();
switch (kind >>> 3) {
case 1:
// string;
entry.key = reader.string();
break;
case 2:
// string;
entry.value = reader.string();
break;
default:
reader.skipType(kind & 7);
break;
}
}
output.keywords.set(entry.key, entry.value);
})();
break;
case 7:
// bytes;
output.thumbnail = reader.bytes();
break;
case 8:
// string;
output.thumbnail = reader.string();
break;
case 9:
// string;
output.email = reader.string();
break;
case 10:
// Array<IHobby>;
output.hobbies.push(_pdo1(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return output;
};
const _pdo1 = (reader, length = -1) => {
length = length < 0 ? reader.size() : reader.index() + length;
const output = {
id: "",
name: "",
valid: undefined,
};
while (reader.index() < length) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
// string;
output.id = reader.string();
break;
case 2:
// string;
output.name = reader.string();
break;
case 3:
// bool;
output.valid = reader.bool();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return output;
};
return (input) => {
const reader = new __typia_transform__ProtobufReader(input);
return _pdo0(reader);
};
})();Restrictions
Same as the rest of the protobuf surface โ see protobuf.message.
Where to go next
- Encoding values โ
protobuf.encode - Sharing the schema with other services โ
protobuf.message - Numeric and string tags โ Special Tags