From 2e73a0df4604921a0f54b9c3c9bbfe79565cbd65 Mon Sep 17 00:00:00 2001 From: unional Date: Tue, 30 May 2023 00:56:53 -0700 Subject: [PATCH] docs: update doc --- README.md | 393 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 294 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index f967de926a..7c5a76c815 100644 --- a/README.md +++ b/README.md @@ -632,13 +632,13 @@ You can learn more in their respective sections: ### numeric -> [`Numeric`](./ts/numeric/number.ts#L4) +> [`Numeric`](./ts/numeric/numeric_type.ts#L4) -↪️ `parse`: either `number` or `bigint`. +📘 `definition`: `number | bigint`. -> [`Zero`](ts/numeric_plus/number.ts#L9): `0` in `number` or `bigint`. +> [`Zero`](ts/numeric_plus/numeric_type.ts#L9) -⭕ `predicate`: `T === number` +📘 `definition`: `0 | 0n` > [`Integer`](./ts/numeric/integer.ts#L15) @@ -694,46 +694,86 @@ You can learn more in their respective sections: ### object -> `filterKey()`: type adjusted filter by key. +> `filterKey()` -> `findKey()`: type adjusted find by key. +🔨 `utilities`: type adjusted filter by key. -> `forEachKey()`: type adjusted for each by key. +> `findKey()` -> `HasKey`: predicate type checking `T` has key `K`. +🔨 `utilities`: type adjusted find by key. -> `hasKey()`: function of `HasKey`. +> `forEachKey()` -> `IsRecord`: `logical` predicate for `Record`. +🔨 `utilities`: type adjusted for each by key. -> `KeysWithDiffTypes`: gets the keys common in `A` and `B` but with different value type. +> `HasKey` -> `mapKey()`: type adjusted map by key. +🔨 `utilities`: predicate type checking `T` has key `K`. -> `RecordValue`: gets the value type `T`from `Record` [video](https://www.youtube.com/watch?v=1J7xK6FUqPw). +> `hasKey()` + +🔨 `utilities`: function of `HasKey`. + +> `IsRecord` + +🔨 `utilities`: `logical` predicate for `Record`. + +> `KeysWithDiffTypes` + +🔨 `utilities`: gets the keys common in `A` and `B` but with different value type. + +> `mapKey()` + +🔨 `utilities`: type adjusted map by key. + +> `RecordValue` + +🔨 `utilities`: gets the value type `T`from `Record` + +[video](https://www.youtube.com/watch?v=1J7xK6FUqPw). + +> `reduceByKey()` -> `reduceByKey()`: type adjusted reduce by key. +🔨 `utilities`: type adjusted reduce by key. -> `someKey()`: type adjusted some by key. +> `someKey()` -> `SpreadRecord`: type for `{...a, ...b}` when both `a` and `b` are `Record`\ +🔨 `utilities`: type adjusted some by key. + +> `SpreadRecord` + +🔨 `utilities`: type for `{...a, ...b}` when both `a` and `b` are `Record`\ for array, just do `[...A, ...B]`. ### Promise -> `AwaitedProp`: `Awaited` on specified props `P` in `T`. +> `AwaitedProp` + +🔨 `utilities`: `Awaited` on specified props `P` in `T`. + +> `isPromise(subject: any)` + +🔨 `utilities`: `isPromise()` type guard. + +> `MaybePromise` + +🔨 `utilities`: Alias of `T | Promise`. -> `isPromise(subject: any)`: `isPromise()` type guard. +> `PromiseValue

` -> `MaybePromise`: Alias of `T | Promise`. +🔨 `utilities`: Gets the type within the Promise. -> `PromiseValue

`: Gets the type within the Promise. +> `PromiseValueMerge` -> `PromiseValueMerge`: Merge the values of multiple promises. +🔨 `utilities`: Merge the values of multiple promises. -> `mapSeries()`: Similar to `bluebird.mapSeries()` but works with `async`/`await`. +> `mapSeries()` -> `transformMaybePromise(value, transformer)`: Apply the `transformer` to the `value`.\ +🔨 `utilities`: Similar to `bluebird.mapSeries()` but works with `async`/`await`. + +> `transformMaybePromise(value, transformer)` + +🔨 `utilities`: Apply the `transformer` to the `value`.\ It is also exported under `MaybePromise.transform()`. ### string @@ -846,25 +886,43 @@ You can learn more in their respective sections: ## Constant Types -> `KeyTypes`: type of all keys. +> `KeyTypes` + +📘 `definition`: type of all keys. + +> `PrimitiveTypes` + +📘 `definition`: all primitive types, including `Function`, `symbol`, and `bigint`. + +> `ComposableTypes` -> `PrimitiveTypes`: all primitive types, including `Function`, `symbol`, and `bigint`. +📘 `definition`: Types that can contain custom properties. i.e. `object`, `array`, `function`. -> `ComposableTypes`: Types that can contain custom properties. i.e. `object`, `array`, `function`. +> `NonComposableTypes` -> `NonComposableTypes`: Types that cannot contain custom properties. i.e. not composable. +📘 `definition`: Types that cannot contain custom properties. i.e. not composable. ## JSON Support -> `JSONPrimitive`: primitive types valid in JSON +> `JSONPrimitive` -> `JSONObject`: JSON object +📘 `definition`: primitive types valid in JSON -> `JSONArray`: JSON array +> `JSONObject` -> `JSONTypes`: all JSON compatible types. +📘 `definition`: JSON object -> `JSONTypes.get(obj, ...props)`: get a cast value in JSON +> `JSONArray` + +📘 `definition`: JSON array + +> `JSONTypes` + +📘 `definition`: all JSON compatible types. + +> `JSONTypes.get(obj, ...props)` + +🔨 `utilities`: get a cast value in JSON ```ts import { JSONTypes } from 'type-plus' @@ -876,99 +934,188 @@ JSONTypes.get(someJson, 'a', 'b', 1, 'c') // miku ## Type manipulation -> `ANotB`: get object with properties in `A` and not in `B`, including properties with a different value type. +> `ANotB` + +🔨 `utilities`: get object with properties in `A` and not in `B`, including properties with a different value type. + +> `BNotA` + +🔨 `utilities`: flip of `ANotB` + +> `as(subject)` + +🔨 `utilities`: assert `subject` as `T`. Avoid ASI issues such as `;(x as T).abc` + +> `asAny(subject)` + +🔨 `utilities`: assert `subject` as `any`. Avoid ASI issue such as `;(x as any).abc` + +> `EitherAnd` + +💀🔨 `deprecated`,`utilities`: Renamed to `EitherOrBoth`. combines 2 to 4 types as `A | B | (A & B)`. + +This is useful for combining options. + +> `EitherOrBoth` + +🔨 `utilities`: combines 2 to 4 types as `A | B | (A & B)`. + +This is useful for combining options [video](https://youtu.be/jBxx03NT4Ik). + +> `Except` + +💀🔨 `deprecated`,`utilities`: same as `Omit`. + +> `ExcludePropType` + +🔨 `utilities`: excludes type `U` from properties in `T`. + +> `KeyofOptional` + +🔨 `utilities`: `keyof` that works with `Record | undefined`. + +> `KnownKeys` -> `BNotA`: flip of `ANotB` +🔨 `utilities`: extract known (defined) keys from type `T`. -> `as(subject)`: assert `subject` as `T`. Avoid ASI issues such as `;(x as T).abc` +> `LeftJoin` -> `asAny(subject)`: assert `subject` as `any`. Avoid ASI issue such as `;(x as any).abc` +🔨 `utilities`: left join `A` with `B` -> `EitherAnd`: combines 2 to 4 types as `A | B | (A & B)`. This is useful for combining options. **Deprecated**. Renamed to `EitherOrBoth`. +> `NonNull` -> `EitherOrBoth`: combines 2 to 4 types as `A | B | (A & B)`. This is useful for combining options [video](https://youtu.be/jBxx03NT4Ik). +🔨 `utilities`: remove `null` -> `Except`: Deprecated. Same as `Omit`. +> `NonNullable` (built-in) -> `ExcludePropType`: excludes type `U` from properties in `T`. +🔨 `utilities`: adjust the type not to nullable -> `KeyofOptional`: `keyof` that works with `Record | undefined`. +> `NonUndefined` -> `KnownKeys`: extract known (defined) keys from type `T`. +🔨 `utilities`: remove `undefined` -> `LeftJoin`: left join `A` with `B` +> `Omit` -> `NonNull`: remove `null` +🔨 `utilities`: From `T`, pick a set of properties whose keys are not in the union `K`. This is the opposite of `Pick`. -> `NonUndefined`: remove `undefined` +> `OptionalKeys` -> `Omit`: From `T`, pick a set of properties whose keys are not in the union `K`. This is the opposite of `Pick`. +🔨 `utilities`: gets keys of optional properties in `T`. -> `OptionalKeys`: gets keys of optional properties in `T`. +> `PartialExcept` -> `PartialExcept`: Deprecated. Same as `PartialOmit`. +💀🔨 `deprecated`,`utilities`: same as `PartialOmit`. -> `PartialOmit`: makes the properties not specified in `U` becomes optional. +> `PartialOmit` -> `PartialPick`: makes the properties specified in `U` becomes optional. +🔨 `utilities`: makes the properties not specified in `U` becomes optional. -> `Pick`: pick properties `K` from `T`. Works with unions. +> `PartialPick` -> `RecursivePartial`: make type `T` optional recursively. +🔨 `utilities`: makes the properties specified in `U` becomes optional. -> `RecursiveRequired`: make type `T` required recursively. +> `Pick` -> `ReplaceProperty`: replace property `K` in `T` with `V`. +🔨 `utilities`: pick properties `K` from `T`. Works with unions. -> `RequiredKeys`: gets keys of required properties in `T`. +> `RecursivePartial` -> `RequiredPick`: makes the properties specified in `U` become required. +🔨 `utilities`: make type `T` optional recursively. -> `RequiredExcept`: makes the properties not specified in `U` become required. +> `RecursiveRequired` -> `RecursiveIntersect`: intersect type `U` onto `T` recursively. +🔨 `utilities`: make type `T` required recursively. -> `ValueOf`: type of the value of the properties of `T`. +> `ReplaceProperty` -> `Widen`: widen literal types. +🔨 `utilities`: replace property `K` in `T` with `V`. -> PropType: ...no helper type for this. Just do `YourType['propName']`. +> `RequiredKeys` + +🔨 `utilities`: gets keys of required properties in `T`. + +> `RequiredPick` + +🔨 `utilities`: makes the properties specified in `U` become required. + +> `RequiredExcept` + +🔨 `utilities`: makes the properties not specified in `U` become required. + +> `RecursiveIntersect` + +🔨 `utilities`: intersect type `U` onto `T` recursively. + +> `ValueOf` + +🔨 `utilities`: type of the value of the properties of `T`. + +> `Widen` + +🔨 `utilities`: widen literal types. + +PropType + +💀 ...no helper type for this. Just do `YourType['propName']`. ## Type Predicates Type predicates are type alias that returns `true` or `false`. They can be used to compose complex types. -> `HasKey`: predicate type checking `T` has key `K`. +> `HasKey` -> `IsAny`: `T === any` (updated to impl: [expect-type]). +🔨 `utilities`: predicate type checking `T` has key `K`. -> `IsBoolean`: check for `boolean`, but not for `true` nor `false`. +> `IsAny` -> `IsDisjoint`: is `A` and `B` is a disjoint set. +🔨 `utilities`: `T === any` (updated to impl: [expect-type]). -> `IsEmptyObject`: is `T === {}`. +> `IsBoolean` -> `IsLiteral`: is `T` a literal type (literal string or number). +🔨 `utilities`: check for `boolean`, but not for `true` nor `false`. + +> `IsDisjoint` + +🔨 `utilities`: is `A` and `B` is a disjoint set. + +> `IsEmptyObject` + +🔨 `utilities`: is `T === {}`. + +> `IsLiteral` + +🔨 `utilities`: is `T` a literal type (literal string or number). ### Logical -> `If`: if statement. +> `If` + +🔨 `utilities`: if statement -> `And`: logical `AND`. +> `And` -> `Or`: logical `OR`. +🔨 `utilities`: logical `AND` -> `Xor`: logical `XOR`. +> `Or` -> `Not`: logical `NOT`. +🔨 `utilities`: logical `OR` + +> `Xor` + +🔨 `utilities`: logical `XOR` + +> `Not` + +🔨 `utilities`: logical `NOT` Note that these types work correctly with the `boolean` type. e.g.: -> `And -> boolean` - -> `Not -> boolean` +```ts +type R = And // boolean +type R = Not // boolean` +``` There is a problem with generic distribution: So you may encounter some weird behavior if your logic is complex. @@ -981,21 +1128,37 @@ It works with `number` and `bigint`, positive and negative number, including flo It will cast the type between `number` and `bigint` if needed. -> `Abs`: `Abs(N)`. +> `Abs` + +🔨 `utilities`: `Abs(N)`. + +> `Max` + +🔨 `utilities`: `max(A, B)` + +> `GreaterThan` + +🔨 `utilities`: `A > B`. + +> `Add` -> `Max`: `max(A, B)` +🔨 `utilities`: `A + B`. -> `GreaterThan`: `A > B`. +> `Subtract` -> `Add`: `A + B`. +🔨 `utilities`: `A > B`. -> `Subtract`: `A > B`. +> `Increment` -> `Increment`: alias of `Add`. +🔨 `utilities`: alias of `Add`. -> `Decrement`: alias of `Subtract`. +> `Decrement` -> `Multiply`. + +> `Multiply `omit(obj, ...props)`: omit properties from `obj`. +> `omit(obj, ...props)` + +🔨 `utilities`: omit properties from `obj`. + +> `pick(obj, ...props)` + +🔨 `utilities`: pick properties from `obj`. + +> `record(value?)` -> `pick(obj, ...props)`: pick properties from `obj`. +🔨 `utilities`: create a `Record` without extra object prototype. -> `record(value?)`: create a `Record` without extra object prototype. +> `record(value?)` -> `record(value?)`: create a record `R` (e.g. `{ a: number }`) without extra object prototype. +🔨 `utilities`: create a record `R` (e.g. `{ a: number }`) without extra object prototype. -> `required(...)`: merge options and remove `Partial`. From [`unpartial`](https://github.com/unional/unpartial) +> `required(...)` -> `requiredDeep(...)`: merge options deeply and remove `Partial`. From [`unpartial`](https://github.com/unional/unpartial) +🔨 `utilities`: merge options and remove `Partial`. From [`unpartial`](https://github.com/unional/unpartial) -> `split(target, ...splitters)`: split one object into multiple objects. +> `requiredDeep(...)` -> `stub(value)`: stub a particular type `T`. +🔨 `utilities`: merge options deeply and remove `Partial`. From [`unpartial`](https://github.com/unional/unpartial) -> `stub.build(init?)`: build a stub for particular type `T`. +> `split(target, ...splitters)` -> `typeOverrideIncompatible()`: override only the incompatible portion between two types. +🔨 `utilities`: split one object into multiple objects. + +> `stub(value)` + +🔨 `utilities`: stub a particular type `T`. + +> `stub.build(init?)` + +🔨 `utilities`: build a stub for particular type `T`. + +> `typeOverrideIncompatible()` + +🔨 `utilities`: override only the incompatible portion between two types. ```ts type A = { @@ -1065,10 +1248,16 @@ const source = { overrider(source, { foo: !!source.foo }) ``` -> `unpartial()`: merge options and remove `Partial` values. From [`unpartial`](https://github.com/unional/unpartial) +> `unpartial()` -> `context()`: a context builder. This is useful to build context for functional programming.\ - It is a sync version of the `AsyncContext` from [async-fp](https://unional/async-fp). +🔨 `utilities`: merge options and remove `Partial` values. From [`unpartial`](https://github.com/unional/unpartial) + +> `context()` + +🔨 `utilities`: a context builder. + +This is useful to build context for functional programming. +It is a sync version of the `AsyncContext` from [async-fp](https://unional/async-fp). ```ts import { context } from 'type-plus' @@ -1129,7 +1318,9 @@ but `Flavor` of the same name cannot be assigned to `Brand`. `nominalMatch(a, b)`: -`nominalMatch()` can be used to compare `Brand` or `Flavor`. +🔨 `utilities`: compare if the two values are nominally equal. + +Works with both `Brand` and `Flavor`. ```ts const b1 = brand('x', 1) @@ -1140,9 +1331,13 @@ nominalMatch(b1, b2) // false ## Functional Types -> `ChainFn: T`: chain function that returns the input type. +> `ChainFn: T` + +🔨 `utilities`: chain function that returns the input type. + +> `compose(...fns): F` -> `compose(...fns): F`: compose functions +🔨 `utilities`: compose functions ## Attribution