Miscellaneous
Three small modules that share the typia transform but don’t fit anywhere else: misc (clone / prune / literals), notations (case conversion), and http (form data / query / headers / route parameters).
misc.clone
namespace misc {
function clone<T>(input: T): Resolved<T>;
function assertClone<T>(input: unknown): Resolved<T>; // + assert
function isClone<T>(input: unknown): Resolved<T> | null; // + is
function validateClone<T>(input: unknown): IValidation<Resolved<T>>; // + validate
}Same family pattern as the validators — clone trusts you, the others wrap the copy with type checking.
const copy = typia.misc.clone<User>(user);
// Type-safe variants
const maybe = typia.misc.isClone<User>(input); // null if `input` isn't a User
const result = typia.misc.validateClone<User>(input); // IValidation<User>
const checked = typia.misc.assertClone<User>(input); // throws if invalidThe pairing rule is the same as elsewhere:
misc.isClone<T>=is<T>+clone<T>misc.assertClone<T>=assert<T>+clone<T>misc.validateClone<T>=validate<T>+clone<T>
undefined
export namespace misc {
export function clone<T>(input: T): Resolved<T>;
export function assertClone<T>(input: T | unknown): Resolved<T>;
export function isClone<T>(input: T | unknown): Resolved<T> | null;
export function validateClone<T>(input: T | unknown): IValidation<Resolved<T>>;
// Factories (Resolved<T> = T projected for the JS runtime)
export function createClone<T>(): (input: T) => Resolved<T>;
export function createAssertClone<T>(): (input: T | unknown) => Resolved<T>;
export function createIsClone<T>(): (input: T | unknown) => Resolved<T> | null;
export function createValidateClone<T>(): (input: T | unknown) => IValidation<Resolved<T>>;
}TypeScript Source
import typia from "typia";
const department: IDepartment = typia.random<IDepartment>();
const cloned: IDepartment = typia.misc.assertClone<IDepartment>(department);
console.log(cloned);
interface IDepartment {
/** @format uuid */
id: string;
/** @minLength 3 */
name: string;
/** @type int */
limit: number;
clerks: IClerk[];
}
interface IClerk {
name: string;
/**
* @exclusiveMinimum 19
* @maximum 100
*/
age: number;
authority: number;
/** @format date */
joined_at: string;
}misc.prune
namespace misc {
function prune<T>(input: T): void; // mutates input
function assertPrune<T>(input: unknown): T; // + assert, then mutates
function isPrune<T>(input: unknown): input is T; // + is; prunes & returns true on match, false (no mutation) on mismatch
function validatePrune<T>(input: unknown): IValidation<T>; // + validate
}prune and assertPrune walk the input object and delete any property not declared on T — they mutate input in place. prune returns void; assertPrune returns the now-mutated input typed as T. The isPrune and validatePrune variants only mutate once they’re sure the input matches T, so they’re safe on values you weren’t expecting.
If you need a non-mutating version, clone first: typia.misc.prune<T>(typia.misc.clone<T>(value)).
typia.misc.prune<User>(input);
// input is now narrowed in place — extra properties removed.
const cleaned = typia.misc.assertPrune<User>(input);
// Same, but throws if input doesn't match User. Returns input.
if (typia.misc.isPrune<User>(input)) {
// input is User and has been pruned. `input` is now typed as User.
}
const r = typia.misc.validatePrune<User>(input);
// r.success === true means input was a User and is now pruned.Useful when you receive a JSON document with extra fields you’d rather not pass around (e.g. logging, persisting to a DB that’s strict about schema).
TypeScript Source
import typia from "typia";
const department: IDepartment = typia.random<IDepartment>();
const pruned: IDepartment = typia.misc.assertPrune<IDepartment>(department);
console.log(pruned);
interface IDepartment {
/** @format uuid */
id: string;
/** @minLength 3 */
name: string;
/** @type int */
limit: number;
clerks: IClerk[];
}
interface IClerk {
name: string;
/**
* @exclusiveMinimum 19
* @maximum 100
*/
age: number;
authority: number;
/** @format date */
joined_at: string;
}misc.literals
namespace misc {
function literals<T extends boolean | number | string | bigint | null>(): T[];
}If you have a string-literal union ("red" | "green" | "blue") and you want the runtime array ["red", "green", "blue"] to iterate over, misc.literals reads the union from the TS type and emits the array.
Handy for select-box options, discriminated-union test matrices, etc.
TypeScript Source
import typia from "typia";
typia.misc.literals<"A" | "B" | "C" | 1 | 2n>();notations
Three case converters: camel, pascal, snake. Each one walks the object and rewrites property names to that case at type and runtime. Same four-variant family as everywhere else (name, assertName, isName, validateName, plus create* factories).
camel
namespace notations {
function camel<T>(input: T): CamelCase<T>;
function assertCamel<T>(input: unknown): CamelCase<T>;
function isCamel<T>(input: unknown): CamelCase<T> | null;
function validateCamel<T>(input: unknown): IValidation<CamelCase<T>>;
}typia.notations.camel<{ user_id: string; user_name: string }>({
user_id: "1",
user_name: "John",
});
// → { userId: "1", userName: "John" }TypeScript Source
import typia from "typia";
interface IPerson {
is_my_name_samchon?: boolean;
HelloTheNewWorld: string;
ToHTML: string;
}
typia.notations.createCamel<IPerson>();pascal
namespace notations {
function pascal<T>(input: T): PascalCase<T>;
function assertPascal<T>(input: unknown): PascalCase<T>;
function isPascal<T>(input: unknown): PascalCase<T> | null;
function validatePascal<T>(input: unknown): IValidation<PascalCase<T>>;
}TypeScript Source
import typia from "typia";
interface IPerson {
is_my_name_samchon?: boolean;
helloTheNewWorld: string;
toHTML: string;
}
typia.notations.createPascal<IPerson>();snake
namespace notations {
function snake<T>(input: T): SnakeCase<T>;
function assertSnake<T>(input: unknown): SnakeCase<T>;
function isSnake<T>(input: unknown): SnakeCase<T> | null;
function validateSnake<T>(input: unknown): IValidation<SnakeCase<T>>;
}typia.notations.snake<{ userId: string; userName: string }>({
userId: "1",
userName: "John",
});
// → { user_id: "1", user_name: "John" }TypeScript Source
import typia from "typia";
interface IPerson {
isMyNameSamchon?: boolean;
HelloTheNewWorld: string;
ToHTML: string;
}
typia.notations.createSnake<IPerson>();http
The http module turns HTTP-shaped inputs (URLSearchParams, headers object, route parameter strings, FormData) into typed objects, with automatic string-to-number / string-to-boolean coercion.
http.query — URL query strings
namespace http {
function query<T extends object>(input: string | IReadableURLSearchParams): Resolved<T>;
function assertQuery<T extends object>(input: string | IReadableURLSearchParams): Resolved<T>;
function isQuery<T extends object>(input: string | IReadableURLSearchParams): Resolved<T> | null;
function validateQuery<T extends object>(input: string | IReadableURLSearchParams): IValidation<Resolved<T>>;
}http.query decodes a query string (or any IReadableURLSearchParams-shaped object — the standard URLSearchParams works, as does Hono’s and other duck-typed shims) into a typed object. Numeric and boolean properties are coerced from their string form automatically.
Restrictions (typia rejects at compile time):
Tmust be an object type- No dynamic keys
- Only
boolean | bigint | number | stringor arrays of those - No unions
http.query itself doesn’t validate constraint tags (Format, Minimum, …). The assertQuery / isQuery / validateQuery variants do.
TypeScript Source
import typia from "typia";
interface IQuery {
limit?: number;
enforce: boolean;
values?: string[];
atomic: string | null;
indexes: number[];
}
typia.http.createQuery<IQuery>();http.headers — HTTP request headers
namespace http {
function headers<T extends object>(
input: Record<string, string | string[] | undefined>,
): Resolved<T>;
// …assert / is / validate variants
}http.headers decodes an Express/Fastify-style headers object. Same coercion as query, plus a stricter set of restrictions specific to HTTP:
-
Tmust be an object type -
No dynamic keys
-
Property keys must be lowercase (HTTP headers are case-insensitive; typia normalizes to lowercase)
-
Property values may be
undefinedbut notnull -
Only
boolean | bigint | number | stringor arrays of those -
No unions
-
set-cookiemust be an array -
These headers cannot be array-typed (the HTTP spec mandates a single value):
ageauthorizationcontent-lengthcontent-typeetagexpiresfromhostif-modified-sinceif-unmodified-sincelast-modifiedlocationmax-forwardsproxy-authorizationrefererretry-afterserveruser-agent
If you trip one of these rules, typia rejects the call at compile time with a clear error.
TypeScript Source
import typia from "typia";
interface IHeaders {
"x-Category": "x" | "y" | "z";
"x-MEMO"?: string;
"x-nAmE"?: string;
"x-Values": number[];
"x-FlAgS": boolean[];
"X-Descriptions": string[];
}
typia.http.createHeaders<IHeaders>();http.parameter — URL path parameters
namespace http {
function parameter<T extends boolean | bigint | number | string | null>(input: string): Resolved<T>;
}http.parameter decodes a single URL path parameter (a string from :id in your route) into the expected primitive type, and always asserts. Unlike query / headers / formData, there is no isParameter, validateParameter, or createParameter — a single path-parameter string is either parseable into T or it isn’t, so typia exposes only the asserting form. If the value doesn’t match T, it throws TypeGuardError.
const id: number = typia.http.parameter<number>(request.params.id);
// throws if `request.params.id` isn't a valid number stringTypeScript Source
import typia, { tags } from "typia";
typia.http.createParameter<string & tags.Format<"uuid">>();
typia.http.createParameter<number & tags.Type<"uint32">>();http.formData — multipart form data
namespace http {
function formData<T extends object>(input: FormData): Resolved<T>;
// …assert / is / validate variants
}http.formData decodes a FormData instance into a typed object. Allowed property types: boolean | bigint | number | string | Blob | File or arrays of those.