import { Format } from "../tags/Format"; 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 JSON-serializable primitive form. * * `Primitive` transforms types for JSON serialization: boxed primitives * become primitives (Boolean→boolean), classes become plain objects with * methods removed, Date becomes `string & Format<"date-time">`, and types with * `toJSON()` use their return type. Native classes (except Date) and bigint * become `never` as they're not JSON-serializable. * * @author Jeongho Nam - https://github.com/samchon * @author Kyungsu Kang - https://github.com/kakasoo * @author Michael - https://github.com/8471919 * @template T Target type to convert */ export type Primitive = Equal> extends true ? T : PrimitiveMain; type PrimitiveMain = Instance extends [never] ? never // (special trick for jsonable | null) type : ValueOf extends bigint ? never : ValueOf extends boolean | number | string ? ValueOf : Instance extends Function ? never : ValueOf extends object ? Instance extends object ? Instance extends Date ? string & Format<"date-time"> : Instance extends IJsonable ? ValueOf extends object ? Raw extends object ? PrimitiveObject // object would be primitified : never // cannot be : ValueOf // atomic value : Instance extends Exclude ? never : PrimitiveObject // object would be primitified : never // cannot be : ValueOf; type PrimitiveObject = Instance extends Array ? IsTuple extends true ? PrimitiveTuple : PrimitiveMain[] : { [P in keyof Instance]: PrimitiveMain; }; type PrimitiveTuple = T extends [] ? [] : T extends [infer F] ? [PrimitiveMain] : T extends [infer F, ...infer Rest extends readonly any[]] ? [PrimitiveMain, ...PrimitiveTuple] : T extends [(infer F)?] ? [PrimitiveMain?] : T extends [(infer F)?, ...infer Rest extends readonly any[]] ? [PrimitiveMain?, ...PrimitiveTuple] : []; interface IJsonable { toJSON(): T; }