@arktype/util
Advanced tools
Comparing version 0.0.16 to 0.0.17
@@ -36,18 +36,18 @@ import type { evaluate } from "./generics.js" | ||
: data extends object | ||
? "object" | ||
: data extends string | ||
? "string" | ||
: data extends number | ||
? "number" | ||
: data extends boolean | ||
? "boolean" | ||
: data extends undefined | ||
? "undefined" | ||
: data extends null | ||
? "null" | ||
: data extends bigint | ||
? "bigint" | ||
: data extends symbol | ||
? "symbol" | ||
: never | ||
? "object" | ||
: data extends string | ||
? "string" | ||
: data extends number | ||
? "number" | ||
: data extends boolean | ||
? "boolean" | ||
: data extends undefined | ||
? "undefined" | ||
: data extends null | ||
? "null" | ||
: data extends bigint | ||
? "bigint" | ||
: data extends symbol | ||
? "symbol" | ||
: never | ||
@@ -62,5 +62,5 @@ export const domainOf = <data>(data: data) => { | ||
: builtinType === "function" | ||
? "object" | ||
: builtinType | ||
? "object" | ||
: builtinType | ||
) as domainOf<data> | ||
} |
@@ -59,1 +59,15 @@ import { throwInternalError } from "./errors.js" | ||
} | ||
export const Callable: Callable = class { | ||
constructor(f: Function, thisArg?: object) { | ||
return Object.setPrototypeOf( | ||
f.bind(thisArg ?? this), | ||
this.constructor.prototype | ||
) | ||
} | ||
} as never | ||
export type Callable = new <f extends (...args: never[]) => unknown>( | ||
f: f, | ||
thisArg?: object | ||
) => f |
@@ -20,3 +20,3 @@ import type { ErrorMessage } from "./errors.js" | ||
export type exact<t extends object, u extends object> = { | ||
[k in keyof t]: k extends keyof u ? t[k] : never | ||
[k in keyof t]: k extends keyof u ? conform<t[k], u[k]> : never | ||
} | ||
@@ -26,3 +26,3 @@ | ||
[k in keyof t]: k extends keyof u | ||
? t[k] | ||
? conform<t[k], u[k]> | ||
: ErrorMessage<`'${k & string}' is not a valid key`> | ||
@@ -29,0 +29,0 @@ } |
@@ -57,12 +57,12 @@ import type { domainOf } from "./domain.js" | ||
: // if done and non-empty, we've reached a variadic element | ||
// (or it's just a normal array, since number[] === [...number[]]) | ||
mode extends "parameters" | ||
? rState["tail"] | ||
: [] | ||
// (or it's just a normal array, since number[] === [...number[]]) | ||
mode extends "parameters" | ||
? rState["tail"] | ||
: [] | ||
: rState["tail"] extends readonly [] | ||
? mode extends "parameters" | ||
? lState["tail"] | ||
: [] | ||
: // if we've reached a variadic element in both arrays, intersect them | ||
Hkt.apply<intersector, [lState["head"], rState["head"]]>[]) | ||
? mode extends "parameters" | ||
? lState["tail"] | ||
: [] | ||
: // if we've reached a variadic element in both arrays, intersect them | ||
Hkt.apply<intersector, [lState["head"], rState["head"]]>[]) | ||
] | ||
@@ -78,9 +78,9 @@ : never | ||
: mode extends "parameters" | ||
? true | ||
: // for values, we should stop recursing immediately if we reach the end of a fixed-length array | ||
[true, readonly []] extends | ||
| [lState["done"], lState["tail"]] | ||
| [rState["done"], rState["tail"]] | ||
? false | ||
: true | ||
? true | ||
: // for values, we should stop recursing immediately if we reach the end of a fixed-length array | ||
[true, readonly []] extends | ||
| [lState["done"], lState["tail"]] | ||
| [rState["done"], rState["tail"]] | ||
? false | ||
: true | ||
@@ -107,19 +107,19 @@ type ElementParseResult = { | ||
: params extends readonly [(infer head)?, ...infer tail] | ||
? [tail, params] extends [params, tail] | ||
? { | ||
head: head | ||
optional: true | ||
tail: tail | ||
done: true | ||
} | ||
: { | ||
// Inferring parms often results in optional adding `|undefined`, | ||
// so the goal here is to counteract that. If this | ||
// causes problems, it should be removed. | ||
head: [] extends params ? Exclude<head, undefined> : head | ||
optional: [] extends params ? true : false | ||
tail: tail | ||
done: false | ||
} | ||
: never | ||
? [tail, params] extends [params, tail] | ||
? { | ||
head: head | ||
optional: true | ||
tail: tail | ||
done: true | ||
} | ||
: { | ||
// Inferring parms often results in optional adding `|undefined`, | ||
// so the goal here is to counteract that. If this | ||
// causes problems, it should be removed. | ||
head: [] extends params ? Exclude<head, undefined> : head | ||
optional: [] extends params ? true : false | ||
tail: tail | ||
done: false | ||
} | ||
: never | ||
@@ -129,12 +129,12 @@ export type isDisjoint<l, r> = l & r extends never | ||
: domainOf<l> & domainOf<r> extends never | ||
? true | ||
: [l, r] extends [object, object] | ||
? true extends valueOf<{ | ||
[k in Extract< | ||
keyof l & keyof r, | ||
requiredKeyOf<l> | requiredKeyOf<r> | ||
>]: isDisjoint<l[k], r[k]> | ||
}> | ||
? true | ||
: false | ||
: false | ||
? true | ||
: [l, r] extends [object, object] | ||
? true extends valueOf<{ | ||
[k in Extract< | ||
keyof l & keyof r, | ||
requiredKeyOf<l> | requiredKeyOf<r> | ||
>]: isDisjoint<l[k], r[k]> | ||
}> | ||
? true | ||
: false | ||
: false |
@@ -14,3 +14,4 @@ export * from "./domain.js" | ||
export * from "./serialize.js" | ||
export * from "./strings.js" | ||
export * from "./traits.js" | ||
export * from "./unionToTuple.js" |
14
map.ts
@@ -23,9 +23,9 @@ import type { evaluate } from "./generics.js" | ||
: Extract<transformed, Entry<result["length"]>> extends infer next extends | ||
Entry | ||
? Exclude<transformed, next> extends infer remaining extends Entry | ||
? [transformed] extends [remaining] | ||
? [...result, ...transformed[1][]] | ||
: arrayFromListableEntriesRecurse<remaining, [...result, next[1]]> | ||
: never | ||
: [...result, ...transformed[1][]] | ||
Entry | ||
? Exclude<transformed, next> extends infer remaining extends Entry | ||
? [transformed] extends [remaining] | ||
? [...result, ...transformed[1][]] | ||
: arrayFromListableEntriesRecurse<remaining, [...result, next[1]]> | ||
: never | ||
: [...result, ...transformed[1][]] | ||
@@ -32,0 +32,0 @@ type extractEntrySets<e extends listable<Entry>> = e extends readonly Entry[] |
@@ -111,4 +111,4 @@ import { throwParseError } from "./errors.js" | ||
: `${value}` extends NumberLiteral<infer valueAsNumber> | ||
? valueAsNumber | ||
: never | ||
? valueAsNumber | ||
: never | ||
: messageOnFail | ||
@@ -115,0 +115,0 @@ |
@@ -40,6 +40,6 @@ import { domainOf, type Domain } from "./domain.js" | ||
: data extends Fn | ||
? "Function" | ||
: instantiableObjectKind<data, kinds> extends never | ||
? keyof kinds | undefined | ||
: instantiableObjectKind<data, kinds> | ||
? "Function" | ||
: instantiableObjectKind<data, kinds> extends never | ||
? keyof kinds | undefined | ||
: instantiableObjectKind<data, kinds> | ||
@@ -46,0 +46,0 @@ type instantiableObjectKind< |
@@ -13,2 +13,4 @@ export type Fn<args extends readonly unknown[] = readonly any[], returns = unknown> = (...args: args) => returns; | ||
}; | ||
export declare const Callable: Callable; | ||
export type Callable = new <f extends (...args: never[]) => unknown>(f: f, thisArg?: object) => f; | ||
//# sourceMappingURL=functions.d.ts.map |
@@ -30,2 +30,7 @@ import { throwInternalError } from "./errors.js"; | ||
}; | ||
export const Callable = class { | ||
constructor(f, thisArg) { | ||
return Object.setPrototypeOf(f.bind(thisArg ?? this), this.constructor.prototype); | ||
} | ||
}; | ||
//# sourceMappingURL=functions.js.map |
@@ -13,6 +13,6 @@ import type { ErrorMessage } from "./errors.js"; | ||
export type exact<t extends object, u extends object> = { | ||
[k in keyof t]: k extends keyof u ? t[k] : never; | ||
[k in keyof t]: k extends keyof u ? conform<t[k], u[k]> : never; | ||
}; | ||
export type exactMessageOnError<t extends object, u extends object> = { | ||
[k in keyof t]: k extends keyof u ? t[k] : ErrorMessage<`'${k & string}' is not a valid key`>; | ||
[k in keyof t]: k extends keyof u ? conform<t[k], u[k]> : ErrorMessage<`'${k & string}' is not a valid key`>; | ||
}; | ||
@@ -19,0 +19,0 @@ export type defer<t> = [t][t extends any ? 0 : never]; |
@@ -14,4 +14,5 @@ export * from "./domain.js"; | ||
export * from "./serialize.js"; | ||
export * from "./strings.js"; | ||
export * from "./traits.js"; | ||
export * from "./unionToTuple.js"; | ||
//# sourceMappingURL=main.d.ts.map |
@@ -14,4 +14,5 @@ export * from "./domain.js"; | ||
export * from "./serialize.js"; | ||
export * from "./strings.js"; | ||
export * from "./traits.js"; | ||
export * from "./unionToTuple.js"; | ||
//# sourceMappingURL=main.js.map |
import type { Fn } from "./functions.js"; | ||
import type { defined, evaluate } from "./generics.js"; | ||
import type { intersectUnion } from "./unionToTuple.js"; | ||
export type Dict<k extends string = string, v = unknown> = { | ||
@@ -19,2 +20,7 @@ readonly [_ in k]: v; | ||
}; | ||
export type require<o, maxDepth extends number = 1> = requireRecurse<o, [ | ||
], maxDepth>; | ||
type requireRecurse<o, depth extends 1[], maxDepth extends number> = depth["length"] extends maxDepth ? o : o extends object ? o extends Fn ? o : { | ||
[k in keyof o]-?: requireRecurse<o[k], [...depth, 1], maxDepth>; | ||
} : o; | ||
export type PartialRecord<k extends PropertyKey = PropertyKey, v = unknown> = { | ||
@@ -29,6 +35,3 @@ [_ in k]?: v; | ||
type mutableRecurse<o, depth extends 1[], maxDepth extends number> = depth["length"] extends maxDepth ? o : o extends object ? o extends Fn ? o : { | ||
-readonly [k in keyof o]: mutableRecurse<o[k], [ | ||
...depth, | ||
1 | ||
], maxDepth>; | ||
-readonly [k in keyof o]: mutableRecurse<o[k], [...depth, 1], maxDepth>; | ||
} : o; | ||
@@ -50,3 +53,13 @@ export type entryOf<o> = { | ||
export declare const keysOf: <o extends object>(o: o) => keysOf<o>[]; | ||
export declare const isKeyOf: <k extends string | number | symbol, obj extends object>(k: k, obj: obj) => k is Extract<keyof obj, k>; | ||
export declare const isKeyOf: <k extends string | number | symbol, o extends object>(k: k, o: o) => k is Extract<keyof o, k>; | ||
/** Coalesce keys that exist on one or more branches of a union */ | ||
export type unionKeyOf<t> = keyof intersectUnion<t>; | ||
export type extractKeyed<o extends object, k extends unionKeyOf<o>> = Extract<o, { | ||
[_ in k]?: unknown; | ||
}>; | ||
export declare const hasKey: <o extends object, k extends keyof intersectUnion<o>>(o: o, k: k) => o is Extract<o, { [_ in k]?: unknown; }>; | ||
export type extractDefinedKey<o extends object, k extends unionKeyOf<o>> = evaluate<extractKeyed<o, k> & { | ||
[_ in k]: {} | null; | ||
}>; | ||
export declare const hasDefinedKey: <o extends object, k extends keyof intersectUnion<o>>(o: o, k: k) => o is Extract<o, { [_ in k]?: unknown; }> & { [__1 in k]: {} | null; } extends infer T ? { [k_1 in keyof T]: (Extract<o, { [_ in k]?: unknown; }> & { [__1 in k]: {} | null; })[k_1]; } : never; | ||
export type requiredKeyOf<o> = { | ||
@@ -72,3 +85,3 @@ [k in keyof o]-?: o extends { | ||
export declare const NoopBase: new <t extends object>() => t; | ||
/** @ts-expect-error **/ | ||
/** @ts-expect-error (see DynamicBase) **/ | ||
export declare class CastableBase<t extends object> extends NoopBase<t> { | ||
@@ -75,0 +88,0 @@ } |
export const entriesOf = (o) => Object.entries(o); | ||
export const fromEntries = (entries) => Object.fromEntries(entries); | ||
export const keysOf = (o) => Object.keys(o); | ||
export const isKeyOf = (k, obj) => k in obj; | ||
export const isKeyOf = (k, o) => k in o; | ||
export const hasKey = (o, k) => k in o; | ||
export const hasDefinedKey = (o, k) => o[k] !== undefined; | ||
export const ShallowClone = class { | ||
@@ -15,3 +17,3 @@ constructor(properties) { | ||
}; | ||
/** @ts-expect-error **/ | ||
/** @ts-expect-error (see DynamicBase) **/ | ||
export class CastableBase extends NoopBase { | ||
@@ -18,0 +20,0 @@ } |
{ | ||
"name": "@arktype/util", | ||
"version": "0.0.16", | ||
"version": "0.0.17", | ||
"author": { | ||
@@ -5,0 +5,0 @@ "name": "David Blass", |
import type { Fn } from "./functions.js" | ||
import type { defined, evaluate } from "./generics.js" | ||
import type { intersectUnion } from "./unionToTuple.js" | ||
@@ -21,2 +22,22 @@ export type Dict<k extends string = string, v = unknown> = { | ||
export type require<o, maxDepth extends number = 1> = requireRecurse< | ||
o, | ||
[], | ||
maxDepth | ||
> | ||
type requireRecurse< | ||
o, | ||
depth extends 1[], | ||
maxDepth extends number | ||
> = depth["length"] extends maxDepth | ||
? o | ||
: o extends object | ||
? o extends Fn | ||
? o | ||
: { | ||
[k in keyof o]-?: requireRecurse<o[k], [...depth, 1], maxDepth> | ||
} | ||
: o | ||
export type PartialRecord<k extends PropertyKey = PropertyKey, v = unknown> = { | ||
@@ -41,12 +62,8 @@ [_ in k]?: v | ||
: o extends object | ||
? o extends Fn | ||
? o | ||
: { | ||
-readonly [k in keyof o]: mutableRecurse< | ||
o[k], | ||
[...depth, 1], | ||
maxDepth | ||
> | ||
} | ||
: o | ||
? o extends Fn | ||
? o | ||
: { | ||
-readonly [k in keyof o]: mutableRecurse<o[k], [...depth, 1], maxDepth> | ||
} | ||
: o | ||
@@ -87,7 +104,30 @@ export type entryOf<o> = { | ||
export const isKeyOf = <k extends string | number | symbol, obj extends object>( | ||
export const isKeyOf = <k extends string | number | symbol, o extends object>( | ||
k: k, | ||
obj: obj | ||
): k is Extract<keyof obj, k> => k in obj | ||
o: o | ||
): k is Extract<keyof o, k> => k in o | ||
/** Coalesce keys that exist on one or more branches of a union */ | ||
export type unionKeyOf<t> = keyof intersectUnion<t> | ||
export type extractKeyed<o extends object, k extends unionKeyOf<o>> = Extract< | ||
o, | ||
{ [_ in k]?: unknown } | ||
> | ||
export const hasKey = <o extends object, k extends unionKeyOf<o>>( | ||
o: o, | ||
k: k | ||
): o is extractKeyed<o, k> => k in o | ||
export type extractDefinedKey< | ||
o extends object, | ||
k extends unionKeyOf<o> | ||
> = evaluate<extractKeyed<o, k> & { [_ in k]: {} | null }> | ||
export const hasDefinedKey = <o extends object, k extends unionKeyOf<o>>( | ||
o: o, | ||
k: k | ||
): o is extractDefinedKey<o, k> => (o as any)[k] !== undefined | ||
export type requiredKeyOf<o> = { | ||
@@ -122,3 +162,3 @@ [k in keyof o]-?: o extends { [_ in k]-?: o[k] } ? k : never | ||
/** @ts-expect-error **/ | ||
/** @ts-expect-error (see DynamicBase) **/ | ||
export class CastableBase<t extends object> extends NoopBase<t> {} | ||
@@ -125,0 +165,0 @@ |
@@ -29,14 +29,14 @@ import { domainOf, type inferDomain, type Primitive } from "./domain.js" | ||
: t extends Primitive | ||
? snapshotPrimitive<t> | ||
: t extends Function | ||
? `(function${string})` | ||
: t extends Date | ||
? string | ||
: depth["length"] extends 10 | ||
? unknown | ||
: t extends List<infer item> | ||
? List<snapshot<item, [...depth, 1]>> | ||
: { | ||
[k in keyof t]: snapshot<t[k], [...depth, 1]> | ||
} | ||
? snapshotPrimitive<t> | ||
: t extends Function | ||
? `(function${string})` | ||
: t extends Date | ||
? string | ||
: depth["length"] extends 10 | ||
? unknown | ||
: t extends List<infer item> | ||
? List<snapshot<item, [...depth, 1]>> | ||
: { | ||
[k in keyof t]: snapshot<t[k], [...depth, 1]> | ||
} | ||
@@ -46,6 +46,6 @@ type snapshotPrimitive<t> = t extends undefined | ||
: t extends bigint | ||
? `${t}n` | ||
: t extends symbol | ||
? `(symbol${string})` | ||
: t | ||
? `${t}n` | ||
: t extends symbol | ||
? `(symbol${string})` | ||
: t | ||
@@ -136,4 +136,4 @@ export const print = (data: unknown, indent?: number) => | ||
: typeof value === "bigint" | ||
? `${value}n` | ||
: `${value}`) as serializePrimitive<value> | ||
? `${value}n` | ||
: `${value}`) as serializePrimitive<value> | ||
@@ -144,3 +144,3 @@ export type serializePrimitive<value extends SerializablePrimitive> = | ||
: value extends bigint | ||
? `${value}n` | ||
: `${value}` | ||
? `${value}n` | ||
: `${value}` |
@@ -69,9 +69,9 @@ import { hasDomain } from "./domain.js" | ||
: k extends keyof Trait | ||
? undefined | ||
: traitsImplementingKey<traits, k> extends infer implementations extends | ||
TraitConstructor[] | ||
? implementations["length"] extends 1 | ||
? undefined | ||
: implementations[number] | ||
: never | ||
? undefined | ||
: traitsImplementingKey<traits, k> extends infer implementations extends | ||
TraitConstructor[] | ||
? implementations["length"] extends 1 | ||
? undefined | ||
: implementations[number] | ||
: never | ||
}> | ||
@@ -78,0 +78,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
205202
94
3077