import type { BaseMappedPropInner, OptionalMappedPropInner, Prop } from "@ark/schema"; import type { arkGet, arkIndexableOf, arkKeyOf, array, ErrorType, inferred, intersectUnion, JsonStructure, Key, listable, merge, optionalKeyOf, show, toArkKey } from "@ark/util"; import type { Default, withDefault } from "../attributes.ts"; import type { type } from "../keywords/keywords.ts"; import type { ArrayType } from "./array.ts"; import type { BaseType } from "./base.ts"; import type { instantiateType } from "./instantiate.ts"; /** @ts-ignore cast variance */ interface Type extends BaseType { readonly(): t extends array ? ArrayType<{ readonly [i in keyof t]: t[i]; }, $> : Type<{ readonly [k in keyof t]: t[k]; }, $>; keyof(): instantiateType, $>; /** * Get the `Type` of a property of this `Type`. * @example type({ foo: "string" }).get("foo") // Type */ get, r = instantiateType, $>>(k1: k1 | type.cast): r extends infer _ ? _ : never; get, const k2 extends arkIndexableOf>, r = instantiateType, k2>, $>>(k1: k1 | type.cast, k2: k2 | type.cast): r extends infer _ ? _ : never; get, const k2 extends arkIndexableOf>, const k3 extends arkIndexableOf, k2>>, r = instantiateType, k2>, k3>, $>>(k1: k1 | type.cast, k2: k2 | type.cast, k3: k3 | type.cast): r extends infer _ ? _ : never; /** * Create a copy of this `Type` with only the specified properties. * @example type({ foo: "string", bar: "number" }).pick("foo") // Type<{ foo: string }> */ pick = never>(...keys: (key | type.cast)[]): Type<{ [k in keyof t as Extract, key>]: t[k]; }, $>; /** * Create a copy of this `Type` with all properties except the specified ones. * @example type({ foo: "string", bar: "number" }).omit("foo") // Type<{ bar: number }> */ omit = never>(...keys: (key | type.cast)[]): Type<{ [k in keyof t as Exclude, key>]: t[k]; }, $>; /** * Merge another `Type` definition, overriding properties of this `Type` with the duplicate keys. * @example type({ a: "1", b: "2" }).merge({ b: "3", c: "4" }) // Type<{ a: 1, b: 3, c: 4 }> */ merge, r = Type, $>>(def: type.validate & (inferredDef extends object ? unknown : ErrorType<[NonObjectMergeErrorMessage, actual: inferredDef]>)): r extends infer _ ? _ : never; /** * Create a copy of this `Type` with all properties required. * @example const T = type({ "foo?"": "string" }).required() // Type<{ foo: string }> */ required(): Type<{ [k in keyof t]-?: t[k]; }, $>; /** * Create a copy of this `Type` with all properties optional. * @example: const T = type({ foo: "string" }).optional() // Type<{ foo?: string }> */ partial(): Type<{ [k in keyof t]?: t[k]; }, $>; map, r = Type, $>>(flatMapEntry: (entry: typePropOf) => transformed): r extends infer _ ? _ : never; /** * List of property info of this `Type`. * @example type({ foo: "string = "" }).props // [{ kind: "required", key: "foo", value: Type, default: "" }] */ props: array>; } type typePropOf = keyof o extends infer k ? k extends keyof o ? typeProp : never : never; type typeProp = t extends Default ? DefaultedTypeProp : BaseTypeProp ? "optional" : "required", k & Key, t, $>; export interface BaseTypeProp { kind: kind; key: k; value: instantiateType; meta: ArkEnv.meta; toJSON: () => JsonStructure; } export interface DefaultedTypeProp extends BaseTypeProp<"optional", k, v, $> { default: defaultValue; } type MappedTypeProp = BaseMappedTypeProp | OptionalMappedTypeProp; type BaseMappedTypeProp = merge; }>; type OptionalMappedTypeProp = merge; default?: v; }>; type constructMapped> = show>>; type fromTypeProps> = show<{ [prop in props[number] as Extract, { kind: "required"; }>["key"]]: prop["value"][inferred]; } & { [prop in props[number] as Extract, { kind: "optional"; default?: never; }>["key"]]?: prop["value"][inferred]; } & { [prop in props[number] as Extract, { kind: "optional"; default: unknown; }>["key"]]: withDefault; }>; export type NonObjectMergeErrorMessage = "Merged type must be an object"; type applyHomomorphicOptionality = prop["kind"] extends string ? prop : prop & { kind: prop["key"] extends optionalKeyOf ? "optional" : "required"; }; export type { Type as ObjectType };