From 777591b8b8807466b3548d2f2be7d522d1505ce6 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Fri, 19 Apr 2024 06:11:40 -0500 Subject: [PATCH 1/8] breaking change (unpublished): capitalize `of` in types like `indexof` --- .changeset/config.json | 8 +-- readme.md | 2 +- src/any/any.ts | 63 ++++++++++++----------- src/some.ts | 112 ++++++++++++++++++++++------------------- 4 files changed, 101 insertions(+), 84 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index b867eed..d02578d 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -1,11 +1,11 @@ { "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "access": "public", + "baseBranch": "main", "changelog": "@changesets/cli/changelog", "commit": false, "fixed": [], + "ignore": [], "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": [] + "updateInternalDependencies": "patch" } \ No newline at end of file diff --git a/readme.md b/readme.md index 45687e4..8649f70 100644 --- a/readme.md +++ b/readme.md @@ -151,7 +151,7 @@ Looking for something that we don't ship yet? [Raise an issue](https://github.co - [`boolean`](https://github.com/ahrjarrett/any-ts/blob/main/src/boolean/boolean.ts) - [`char`](https://github.com/ahrjarrett/any-ts/blob/main/src/string/char.ts) - [`empty`](https://github.com/ahrjarrett/any-ts/blob/main/src/empty.ts) -- [`Kind`](https://github.com/ahrjarrett/any-ts/blob/main/src/kind/kind.ts) (a [higher-kinded type](https://en.wikipedia.org/wiki/Kind_(type_theory)) encoding that is more ergonomic than any other we've found) +- [`Kind`](https://github.com/ahrjarrett/any-ts/blob/main/src/kind/kind.ts), a simple but powerful [HKT](https://en.wikipedia.org/wiki/Kind_(type_theory)) encoding that supports partial application & re-binding - [`integer`](https://github.com/ahrjarrett/any-ts/blob/main/src/number/integer.ts) - [`mut`](https://github.com/ahrjarrett/any-ts/blob/main/src/mutable/mutable.ts) - [`never`](https://github.com/ahrjarrett/any-ts/blob/main/src/semantic-never/semantic-never.ts), a.k.a. semantic never diff --git a/src/any/any.ts b/src/any/any.ts index 9f6c6bb..5d4f254 100644 --- a/src/any/any.ts +++ b/src/any/any.ts @@ -90,6 +90,7 @@ declare namespace any { export type three = readonly [_1: one, _2: two, _3: three] export type triple = type export type ternary = type + export type record = globalThis.Record> = type export type predicate = type export type asserts = never | some.asserts @@ -129,52 +130,42 @@ declare namespace any { = keyof invariant > = type - export type keysof< + export type keysOf< invariant, type extends | any.array = any.array > = type - export type propertyof< + export type propertyOf< invariant, type extends | any.key & keyof invariant = any.key & keyof invariant > = type - /** - * @deprecated use {@link propertyof `any.propertyof`} or {@link propertyof `any.propertyOf`} instead - */ - export type showableKeyof< - invariant, - type extends - | any.key & keyof invariant - = any.key & keyof invariant - > = type - - export type indexof< + export type indexOf< invariant extends any.array, type extends | Extract = Extract > = type - export type indexedby< + export type indexedBy< invariant extends any.index, type extends | { [ix in invariant]: _ } = { [ix in invariant]: _ } > = type - export type indexableby< + export type indexableBy< invariant extends any.index, type extends | { [ix in invariant]: any.index } = { [ix in invariant]: any.index } > = type - export type pathof< + export type pathOf< invariant, type extends | pathsof @@ -188,40 +179,55 @@ declare namespace any { = { [ix in invariant[0]]: invariant[1] } > = type - export type arrayof< + export type arrayOf< invariant, type extends | any.array = any.array > = type - export type entryof< + export type entryOf< invariant, type extends | readonly [any.index, invariant] = readonly [any.index, invariant] > = type - export type entriesof< + export type entriesOf< invariant, type extends | any.array = any.array > = type - export type fieldof< + export type fieldOf< invariant, type extends | to.entries = to.entries > = type - export type subtypeof< + export type subtypeOf< invariant, subtype extends | invariant extends invariant ? invariant : never = invariant extends invariant ? invariant : never > = subtype + + + export type domainOf< + invariant extends some.function, + target extends + | globalThis.Parameters + = globalThis.Parameters + > = target + + export type codomainOf< + invariant extends some.function, + target extends + | globalThis.ReturnType + = globalThis.ReturnType + > = target } export type any_index = keyof never @@ -236,19 +242,20 @@ export type any_array = readonly type[] /** @ts-expect-error */ export interface any_object extends id { } export type any_struct = { [ix: string]: type } -export interface any_enumerable { [ix: number]: type } -export interface any_arraylike extends any_enumerable { length: number } +export interface any_enumerable { [ix: number]: type } +export interface any_arraylike extends any_enumerable { length: number } export interface any_invertible { [ix: any_key]: any_key } -export type any_field = readonly [key: k, value: v] -export type any_entry = type +export type any_field = readonly [key: key, value: value] +export type any_entry = type export interface any_class< args extends | any.array - = any.array -> { new(...arg: args): _ } + = any.array, + target = _ +> { new(...arg: args): target } export type any_json = | any.scalar - | any_dict | readonly any_json[] + | any_dict ; diff --git a/src/some.ts b/src/some.ts index 597ddae..5a7c5c7 100644 --- a/src/some.ts +++ b/src/some.ts @@ -2,6 +2,7 @@ export type { some } import type { any } from "./any/exports" import type { never } from "./semantic-never/exports" +import type { _ } from "./util" import type { to } from "./to" @@ -29,40 +30,40 @@ declare namespace distributive { } -interface fn = any.array, returns = unknown> { (...arg: args): returns } +interface fn = any.array, cod = _> { (...arg: dom): cod } interface predicate { (u: type): boolean } type guard = never | typeguard -type typeguard = never | typePredicate<[source, target]> +type typeguard = never | typePredicate<[source, target]> type typePredicate< map extends - | readonly [source: unknown, target: unknown] - = readonly [source: any, target: unknown] + | readonly [source: _, target: _] + = readonly [source: any, target: _] > = never | ((u: map[0]) => u is map[1]) -type asserts = never | assertion<[source, target]> +type asserts = never | assertion<[source, target]> type assertion< map extends - | readonly [source: unknown, target: unknown] - = readonly [source: any, target: unknown] + | readonly [source: _, target: _] + = readonly [source: any, target: _] > = never | { (u: map[0]): asserts u is map[1] } -type arrayof< +type arrayOf< invariant, type extends | any.array = any.array > = type -type fieldof< +type fieldOf< invariant, type extends | to.entries = to.entries > = type -type subtypeof< +type subtypeOf< invariant, subtype extends | invariant extends invariant ? invariant : never @@ -80,107 +81,116 @@ interface predicate { (x: type): boolean } /** - * The {@link some `some`} namespace is the dual of {@link any `any`}. + * {@link some `some`} is {@link any `any`}'s {@link https://en.wikipedia.org/wiki/Duality_(mathematics) dual}. * - * Whereas the {@link any `any`} namespace is analogous to + * Explanation: + * + * If {@link any `any`} is analogous to * {@link https://en.wikipedia.org/wiki/Universal_quantification universal quantification} - * (read: "for all"), {@link some `some`} is more closely related to + * (that is, _for all_), then {@link some `some`} corresponds to * {@link https://en.wikipedia.org/wiki/Existential_quantification _existential_ quantification} - * (read: "there exists"). + * (that is, _there exists_). */ declare namespace some { - // aliased exports export { - /** {@link arrayof `some.arrayof`} @external */ - arrayof, - /** {@link arrayof `some.arrayOf`} @external */ - arrayof as arrayOf, /** {@link fn `some.function`} @external */ fn as function, - /** {@link fieldof `some.fieldof`} @external */ - fieldof, - /** {@link fieldof `some.fieldOf`} @external */ - fieldof as fieldOf, - /** {@link subtypeof `some.subtypeof`} @external */ - subtypeof, - /** {@link subtypeof `some.subtypeOf`} @external */ - subtypeof as subtypeOf, } // direct exports export { + /** {@link arrayOf `some.arrayOf`} @external */ + arrayOf, /** {@link assertion `some.assertion`} @external */ assertion, /** {@link asserts `some.asserts`} @external */ asserts, /** {@link binary `some.binary`} @external */ binary, + /** {@link entryOf `some.entryOf`} @external */ + entryOf, /** {@link field `some.field`} @external */ field, + /** {@link fieldOf `some.fieldOf`} @external */ + fieldOf, /** {@link guard `some.guard`} @external */ guard, + /** {@link keyof `some.keyof`} @external */ + keyof, /** {@link named `some.named`} @external */ named, /** {@link predicate `some.predicate`} @external */ predicate, /** {@link record `some.record`} @external */ record, + /** {@link subtypeOf `some.subtypeOf`} @external */ + subtypeOf, /** {@link ternary `some.ternary`} @external */ ternary, /** {@link typeguard `some.typeguard`} @external */ typeguard, /** {@link unary `some.unary`} @external */ unary, + /** {@link valueOf `some.valueOf`} @external */ + valueOf, + /** {@link variadic `some.variadic`} @external */ + variadic, } - /** {@link unary `some.unary`} @external */ interface unary< - out = unknown, - arg = any - > { (_: arg): out } + returns = _, + accepts = any + > { (x: accepts): returns } /** {@link binary `some.binary`} @external */ interface binary< - out = unknown, - arg_0 = any, - arg_1 = any - > { (_0: arg_0, _1: arg_1): out } + returns = _, + x = any, + y = any + > { (x: x, y: y): returns } /** {@link ternary `some.ternary`} @external */ interface ternary< - out = unknown, - arg_0 = any, - arg_1 = any, - arg_2 = any - > { (_0: arg_0, _1: arg_1, _2: arg_2): out } + out = _, + a = any, + b = any, + c = any + > { (x: a, y: b, z: c): out } + + /** {@link variadic `some.variadic`} @external */ + interface variadic< + returns = _, + accepts extends any.array = any.array + > { (...args: accepts): returns } /** {@link field `some.field`} @external */ - type field = any.field + type field = any.field /** {@link record `some.record`} @external */ type record< key extends | any.index = any.key, - value = unknown + value = _ > = globalThis.Record - export type entryof< - invariant extends any.object, - type extends - | distributive.entryof - = distributive.entryof - > = type - - export type keyof< + /** {@link record `some.record`} @external */ + type keyof< invariant, type extends | distributive.keyof = distributive.keyof > = type - export type valueof< + type entryOf< + invariant extends any.object, + type extends + | distributive.entryof + = distributive.entryof + > = type + + type valueOf< invariant, type extends | distributive.values From bab59e531364541a1c4d73f6499baccc0cebe88a Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:16:10 -0500 Subject: [PATCH 2/8] fix: removes internal use of legacy api (arrayof, indexedby, keysof, etc.) --- src/any/any.ts | 4 ---- src/err/enforce.ts | 2 +- src/kind/bind.ts | 2 +- src/lens/focus.ts | 4 ++-- src/lens/tree.ts | 2 +- src/paths/paths.ts | 4 ++-- src/show/associative.ts | 10 +++++----- src/string/_internal.ts | 2 +- src/tree/tree.ts | 2 +- vitest.config.ts | 8 -------- vitest.setup.ts | 5 ----- 11 files changed, 14 insertions(+), 31 deletions(-) delete mode 100644 vitest.config.ts delete mode 100644 vitest.setup.ts diff --git a/src/any/any.ts b/src/any/any.ts index 5d4f254..3de01b8 100644 --- a/src/any/any.ts +++ b/src/any/any.ts @@ -29,12 +29,8 @@ declare namespace any { ///////////////////// /// 🡓🡓 aliases export { - arrayof as arrayOf, dictionary as dict, - indexableby as indexableBy, - indexedby as indexedBy, keyof as keyOf, - keysof as keysOf, } /// 🡑🡑 aliases /////////////////// diff --git a/src/err/enforce.ts b/src/err/enforce.ts index 4833663..114015e 100644 --- a/src/err/enforce.ts +++ b/src/err/enforce.ts @@ -139,7 +139,7 @@ declare namespace enforce { type uniqNonNumericIndex = [type] extends [any.entries] - ? impl.nonnumericIndex extends any.arrayof + ? impl.nonnumericIndex extends any.arrayOf ? Err2<"NonNumericIndex", numerics> : enforce.uniqueness.ofEntries extends infer dupes ? unknown extends dupes ? (unknown) diff --git a/src/kind/bind.ts b/src/kind/bind.ts index c3a329f..ef0e8df 100644 --- a/src/kind/bind.ts +++ b/src/kind/bind.ts @@ -10,7 +10,7 @@ declare namespace Bind { interface four extends Kind<[a, b, c, d]> { [-1]: Kind<[this[0], this[1], this[2], this[3]]> } interface five extends Kind<[a, b, c, d, e]> { [-1]: Kind<[this[0], this[1], this[2], this[3], this[4]]> } - type partial = globalThis.Omit extends any.subtypeof ? next : never + type partial = globalThis.Omit extends any.subtypeOf ? next : never } type __Bind__ = [ diff --git a/src/lens/focus.ts b/src/lens/focus.ts index a578587..c73385a 100644 --- a/src/lens/focus.ts +++ b/src/lens/focus.ts @@ -144,13 +144,13 @@ declare namespace impl { type merge = { [ix in union extends union ? keyof union : never.close.distributive] - : union extends any.indexedby ? union[ix] : never.close.distributive } + : union extends any.indexedBy ? union[ix] : never.close.distributive } ; type mergeTrees = never.as_identity | [union] extends [any.primitive] ? union : { [ix in union extends union ? keyof union : never.close.distributive] - : impl.mergeTrees ? union[ix] : never.close.distributive> } + : impl.mergeTrees ? union[ix] : never.close.distributive> } ; type joinLeft = never.as_identity diff --git a/src/lens/tree.ts b/src/lens/tree.ts index abc92f3..8866bd3 100644 --- a/src/lens/tree.ts +++ b/src/lens/tree.ts @@ -42,7 +42,7 @@ type joinRight = never.as_identity } type fromPaths> - = splitPaths extends any.arrayof, infer split> + = splitPaths extends any.arrayOf, infer split> ? { [ix in keyof split]: traversable.unfold<{}, split[ix]> } extends any.list ? impl.joinTrees : never.close.inline_var<"trees"> diff --git a/src/paths/paths.ts b/src/paths/paths.ts index 6cea3e2..9e732ab 100644 --- a/src/paths/paths.ts +++ b/src/paths/paths.ts @@ -11,7 +11,7 @@ type isOptional type pathsof = Path.go extends - | any.two> + | any.two> ? { [ix in keyof path]: path[ix] extends | any.two ? meta extends typeof Path.Meta.Optional @@ -41,7 +41,7 @@ declare namespace Path { export type array> = number extends type["length"] ? Path.go - : any.indexof extends infer ix + : any.indexOf extends infer ix ? ix extends keyof type ? isOptional extends true ? Path.go, [...path, [𝐤𝐞𝐲: ix, 𝐦𝐞𝐭𝐚: typeof Meta.Optional]]> diff --git a/src/show/associative.ts b/src/show/associative.ts index 1f85342..111fbc1 100644 --- a/src/show/associative.ts +++ b/src/show/associative.ts @@ -51,7 +51,7 @@ type index = acc["length"] extends type[len$ & keyof type] ? acc : index<[ ...acc, - Extract>[acc["length"]]], + Extract>[acc["length"]]], type > ; @@ -120,22 +120,22 @@ declare namespace impl { namespace impl { const assoc_ - : new < const ns extends any.object, const ord extends any.indexedby>(named: ns, order: ord) => ns & ord + : new < const ns extends any.object, const ord extends any.indexedBy>(named: ns, order: ord) => ns & ord = class { - constructor(named: any.object, order: any.indexedby) { + constructor(named: any.object, order: any.indexedBy) { Object.assign(this, order, named); } } as never // @ts-expect-error - internal use only export class assoc< const named extends any.object, - const order extends any.indexedby + const order extends any.indexedBy > extends assoc_ { } } class assoc< tag extends Tag, - const named extends any.object, order extends any.indexedby + const named extends any.object, order extends any.indexedBy > extends impl.assoc<{ [tag$]: tag } & named, order> implements Tagged { diff --git a/src/string/_internal.ts b/src/string/_internal.ts index 2220136..07345d2 100644 --- a/src/string/_internal.ts +++ b/src/string/_internal.ts @@ -238,7 +238,7 @@ type snake ; type pascal - = char.splitOnChar, " "> extends any.arrayof + = char.splitOnChar, " "> extends any.arrayOf ? join<{ [ix in keyof xs]: globalThis.Capitalize> }> : never ; diff --git a/src/tree/tree.ts b/src/tree/tree.ts index c54c81b..1261cb4 100644 --- a/src/tree/tree.ts +++ b/src/tree/tree.ts @@ -22,7 +22,7 @@ type nonempty< type merge = never | [t] extends [any.primitive] ? t : { [k in t extends any.object ? keyof t : never] - : merge ? t[k] : never> } + : merge ? t[k] : never> } ; type shift diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index c59776d..0000000 --- a/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config" - -export default defineConfig({ - test: { - globalSetup: "vitest.setup.ts" - } - -}) diff --git a/vitest.setup.ts b/vitest.setup.ts deleted file mode 100644 index ba617de..0000000 --- a/vitest.setup.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as at from "@arktype/attest" - -export const setup = () => at.setup({}) - -export const teardown = at.cleanup From 966bd201026ff96136a146cd8118bddcc7b9d658 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:21:13 -0500 Subject: [PATCH 3/8] feat: adds `any.pair` --- src/any/any.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/any/any.ts b/src/any/any.ts index 3de01b8..a61a6f1 100644 --- a/src/any/any.ts +++ b/src/any/any.ts @@ -81,6 +81,7 @@ declare namespace any { export type single = type export type unary = type export type two = readonly [_1: one, _2: two] + export type pair = readonly [left: left, right: right] export type double = type export type binary = type export type three = readonly [_1: one, _2: two, _3: three] From 8ca98ad25938ee7960dc648925f4f02019cc5d3c Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:27:45 -0500 Subject: [PATCH 4/8] feat: adds type-checking for generic kinds --- src/evaluate/evaluate.ts | 35 +++++++++++++++++++++++++++++++---- src/kind/bind.ts | 6 ------ src/kind/kind.ts | 14 ++++++++++++-- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/evaluate/evaluate.ts b/src/evaluate/evaluate.ts index f7e1a95..1c74ba0 100644 --- a/src/evaluate/evaluate.ts +++ b/src/evaluate/evaluate.ts @@ -1,4 +1,5 @@ export { + eval, evaluate, } @@ -25,16 +26,42 @@ import type { any } from "../any/exports"; * type bababababab = evaluate * // ^? type bababababab = { b: { a: { b: { a: { b: { a: { b: { a: { b: { a: { b: any } } } } } } } } } } } */ -function evaluate(type: type): evaluate +function evaluate(type: type): eval function evaluate(type: type, maxDepth: maxDepth): evaluate function evaluate(type: type, _max?: maxDepth): unknown { return type } -type evaluate = evaluate.go +/** + * {@link eval `eval`} is semantically equivalent to {@link evaluate `evaluate`} with + * a hardcoded max-depth of 1. + * + * In practice, you should use `eval` when you want a shallow evaluation, because + * TypeScript can make certain optimizations when it knows that an expression does + * not contain any sub-expressions that require recursion. + * + * @example +* import type { eval } from "any-ts" +* +* interface Abc { abc: Def } +* interface Def { def: Ghi } +* interface Ghi { ghi: Abc } +* +* type Purdy = eval +* // ^? type Purdy = { abc: 123, def: 456, ghi: 789 } +*/ +type eval = never | ({ [k in keyof type]: type[k] }) + +/** + * {@link evaluate `evaluate`} "evaluates" an expression. + * + * In practice, you should use {@link eval `eval`} when you want a shallow + * evaluation, because TypeScript can make certain optimizations when it + * knows that an expression does not contain any sub-expressions that require recursion. + */ +type evaluate = evaluate.go declare namespace evaluate { type go = maxDepth extends currentDepth["length"] ? type : type extends any.primitive | any.function ? type - : { [ix in keyof type] - : go } + : { [ix in keyof type]: go } ; } diff --git a/src/kind/bind.ts b/src/kind/bind.ts index ef0e8df..f776201 100644 --- a/src/kind/bind.ts +++ b/src/kind/bind.ts @@ -13,9 +13,3 @@ declare namespace Bind { type partial = globalThis.Omit extends any.subtypeOf ? next : never } -type __Bind__ = [ - Kind.apply, - Kind.apply, - Kind.apply, -] - diff --git a/src/kind/kind.ts b/src/kind/kind.ts index 5299545..a2953e5 100644 --- a/src/kind/kind.ts +++ b/src/kind/kind.ts @@ -122,7 +122,17 @@ type kind = Scope> type parseInt = `${type & any.key}` extends `${infer x extends number}` ? x : never; type structured = never | [type] extends [any.array] ? { [ix in Extract as parseInt]: type[ix] } : type -type satisfies = never | ({ [ix in Exclude]+?: type[ix] }) + +// type satisfies = never | ({ [ix in Exclude]+?: type[ix] }) +type satisfies = never + | ([fn] extends [kind] + ? unknown extends scope + ? { [ix in globalThis.Exclude]: fn[ix] } + : scope + : never + ) + ; + type inferConstraints = fn extends Kind @@ -155,7 +165,7 @@ type slots = cached.slots[cached.prev[arity]] type Arity = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 interface Scope { 0?: _, 1?: _, 2?: _, 3?: _, 4?: _, 5?: _, 6?: _, 7?: _, 8?: _, 9?: _ } -type bind> = never | (fn & structured) +type bind>> = never | (fn & structured) type apply> = bind[-1] type constraintsOf = satisfies> = type From 73804f6c1c26552bd1deb59014ea9f0cd2896e66 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:31:44 -0500 Subject: [PATCH 5/8] feat: adds `object.filter` and `object.filterKeys` --- src/evaluate/exports.ts | 2 +- src/object.ts | 90 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/src/evaluate/exports.ts b/src/evaluate/exports.ts index f1c1cf3..7e82fcb 100644 --- a/src/evaluate/exports.ts +++ b/src/evaluate/exports.ts @@ -1 +1 @@ -export { evaluate } from "./evaluate" \ No newline at end of file +export type { eval, evaluate } from "./evaluate" \ No newline at end of file diff --git a/src/object.ts b/src/object.ts index d4f8636..83bde45 100644 --- a/src/object.ts +++ b/src/object.ts @@ -1,8 +1,88 @@ -export { - object_ as object +import type { any } from "./any/exports" +import type { some } from "./some" +import type { eval } from "./evaluate/exports" + +export declare namespace object { + type filter = { + (guard: any.typeguard): >(object: T) => filter.values + (predicate: some.predicate): >(object: T) => filter.values + >(object: T, guard: any.typeguard): filter.values + >(object: T, predicate: some.predicate,): filter.values + } + + type filterKeys = { + (guard: any.typeguard): >(object: T) => filter.keys + (predicate: some.predicate): >(object: T) => filter.keys + >(object: T, guard: any.typeguard): filter.keys + >(object: T, predicate: some.predicate,): filter.keys + } } -type id = type +declare namespace filter { + type keys = never | + eval< + & filter.keys.satisfy + & filter.keys.partiallySatisfy + & filter.keys.mightSatisfy + > + + namespace keys { + type satisfy = never | + { -readonly [k in keyof t as filter.allSatisfy extends true ? k : never]: t[k] } + type partiallySatisfy = never | + { -readonly [k in keyof t as filter.partiallySatisfy extends true ? k : never]: t[k] } + type mightSatisfy = never | + { -readonly [k in keyof t as filter.mightSatisfy extends true ? k : never]: t[k] } + } + + type values = never | + eval< + & filter.values.satisfy + & filter.values.partiallySatisfy + & filter.values.mightSatisfy + > + + namespace values { + type satisfy = never | + { -readonly [k in keyof t as filter.allSatisfy extends true ? k : never]: t[k] } + type partiallySatisfy = never | + { -readonly [k in keyof t as filter.partiallySatisfy extends true ? k : never]+?: t[k] } + type mightSatisfy = never | + { -readonly [k in keyof t as filter.mightSatisfy extends true ? k : never]+?: filter.cast } + } -interface object_ extends id { } -declare const object_: object_ + type cast + = [distribute] extends [never] + ? (type extends invariant ? type : never) extends infer narrow + ? [narrow] extends [never] ? invariant + : narrow + : never + : type extends type ? filter.cast + : never + ; + + type allSatisfy + = ( + bound extends bound + ? (t extends t & bound ? t : never) extends infer out + ? out + : never + : never + ) extends infer out + ? [t, out] extends [out, t] ? true + : false + : never + ; + + type partiallySatisfy + = filter.allSatisfy extends true ? false + : [bound extends bound ? (t extends bound ? true : never) : never] extends [never] ? false + : true + ; + + type mightSatisfy + = [t] extends [bound] ? never + : [t extends t ? (bound extends t ? true : never) : never] extends [never] ? false + : true + ; +} From e611ada0923efcca441bd71c8a8458a9947a4e17 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:38:10 -0500 Subject: [PATCH 6/8] chore: commits changeset --- .changeset/ninety-cows-bow.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .changeset/ninety-cows-bow.md diff --git a/.changeset/ninety-cows-bow.md b/.changeset/ninety-cows-bow.md new file mode 100644 index 0000000..753a157 --- /dev/null +++ b/.changeset/ninety-cows-bow.md @@ -0,0 +1,17 @@ +--- +"any-ts": patch +--- + +## features +adds: +- `object.filter` +- `object.filterKeys` + +## deprecations +deprecates: +- `any.arrayof` - use `any.arrayOf` instead +- `any.entriesof` - use `any.entriesOf` instead +- `any.entryof` - use `any.entryOf` instead +- `any.keysof` - use `any.keysOf` instead +- `any.subtypeof` - use `any.subtypeOf` instead +- `any.indexedby` - use `any.indexedBy` instead From 5ba07b6f88f7125297602e18ec5e13cca96c1992 Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:45:55 -0500 Subject: [PATCH 7/8] chore: makes `writeVersion` script more robust to bad states --- bin/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/version.ts b/bin/version.ts index d8ae3ed..35a11d9 100755 --- a/bin/version.ts +++ b/bin/version.ts @@ -101,7 +101,7 @@ const versionTemplate: (version: string) => string * published. */ const writeVersion = (v: string): void => { - return void (v && writeFile(versionFile)(versionTemplate(v))) + return void (v && v.length > 0 && writeFile(versionFile)(versionTemplate(v))) } function commitWorktree(version: string): void { From 692d373a72e5afaeed541881f48442350eb02abd Mon Sep 17 00:00:00 2001 From: Andrew Jarrett Date: Sun, 28 Apr 2024 16:48:54 -0500 Subject: [PATCH 8/8] chore: exports `object` module --- src/exports.ts | 2 +- src/object/exports.ts | 1 + src/{ => object}/object.ts | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 src/object/exports.ts rename src/{ => object}/object.ts (96%) diff --git a/src/exports.ts b/src/exports.ts index 3385a46..a3cfa53 100644 --- a/src/exports.ts +++ b/src/exports.ts @@ -9,7 +9,7 @@ export { export type { any } from "./any/exports" export type { some } from "./some" -export type { } from "./associative/exports" +export type { object } from "./object/exports" export type { boolean } from "./boolean/exports" export type { cache } from "./cache/exports" export type { evaluate } from "./evaluate/exports" diff --git a/src/object/exports.ts b/src/object/exports.ts new file mode 100644 index 0000000..4760f20 --- /dev/null +++ b/src/object/exports.ts @@ -0,0 +1 @@ +export type { object } from "./object" diff --git a/src/object.ts b/src/object/object.ts similarity index 96% rename from src/object.ts rename to src/object/object.ts index 83bde45..f39bc51 100644 --- a/src/object.ts +++ b/src/object/object.ts @@ -1,6 +1,6 @@ -import type { any } from "./any/exports" -import type { some } from "./some" -import type { eval } from "./evaluate/exports" +import type { any } from "../any/exports" +import type { some } from "../some" +import type { eval } from "../evaluate/exports" export declare namespace object { type filter = {