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 β deep copy
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 β remove extra properties
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; returns false instead of mutating
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 β union literal type β array
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 β case conversion
Three case converters: camel, pascal, snake. Each one walks the object and rewrites property names to that case. Same four-variant family as everywhere else:
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>>;
}PascalCase and SnakeCase swap in for CamelCase in the type. The output type is computed at the type level so the rest of your code knows about the new property names.
typia.notations.snake<{ userId: string; userName: string }>({
userId: "1",
userName: "John",
});
// β { user_id: "1", user_name: "John" }undefined
export namespace notations {
export function camel<T>(input: T): CamelCase<T>;
export function assertCamel<T>(input: T | unknown): CamelCase<T>;
export function isCamel<T>(input: T | unknown): CamelCase<T> | null;
export function validateCamel<T>(input: T | unknown): IValidation<CamelCase<T>>;
// Same surface for pascal / Pascal and snake / Snake.
// Each has create* factories too.
}camel example
import typia from "typia";
interface IPerson {
is_my_name_samchon?: boolean;
HelloTheNewWorld: string;
ToHTML: string;
}
typia.notations.createCamel<IPerson>();http β decode form data, query strings, headers, route params
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 | URLSearchParams): Resolved<T>;
function assertQuery<T extends object>(input: string | URLSearchParams): Resolved<T>;
function isQuery<T extends object>(input: string | URLSearchParams): Resolved<T> | null;
function validateQuery<T extends object>(input: string | URLSearchParams): IValidation<Resolved<T>>;
}http.query decodes a query string (or a URLSearchParams) 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 collapses them to a single value):
age, authorization, content-length, content-type, etag, expires, from, host, if-modified-since, if-unmodified-since, last-modified, location, max-forwards, proxy-authorization, referer, retry-after, server, user-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): 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, thereβs no isParameter or validateParameter β 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.