ts-data-forge 9.0.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/array/impl/array-utils-creation.d.mts +4 -4
- package/dist/array/impl/array-utils-creation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-creation.mjs +17 -112
- package/dist/array/impl/array-utils-creation.mjs.map +1 -1
- package/dist/array/impl/array-utils-element-access.d.mts.map +1 -1
- package/dist/array/impl/array-utils-element-access.mjs +22 -61
- package/dist/array/impl/array-utils-element-access.mjs.map +1 -1
- package/dist/array/impl/array-utils-iterators.d.mts.map +1 -1
- package/dist/array/impl/array-utils-iterators.mjs +9 -63
- package/dist/array/impl/array-utils-iterators.mjs.map +1 -1
- package/dist/array/impl/array-utils-modification.d.mts +7 -7
- package/dist/array/impl/array-utils-modification.d.mts.map +1 -1
- package/dist/array/impl/array-utils-modification.mjs +78 -78
- package/dist/array/impl/array-utils-modification.mjs.map +1 -1
- package/dist/array/impl/array-utils-reducing-value.mjs +95 -89
- package/dist/array/impl/array-utils-reducing-value.mjs.map +1 -1
- package/dist/array/impl/array-utils-search.mjs +100 -92
- package/dist/array/impl/array-utils-search.mjs.map +1 -1
- package/dist/array/impl/array-utils-set-op.d.mts.map +1 -1
- package/dist/array/impl/array-utils-set-op.mjs +31 -141
- package/dist/array/impl/array-utils-set-op.mjs.map +1 -1
- package/dist/array/impl/array-utils-size.d.mts.map +1 -1
- package/dist/array/impl/array-utils-size.mjs +4 -8
- package/dist/array/impl/array-utils-size.mjs.map +1 -1
- package/dist/array/impl/array-utils-slice-clamped.mjs +11 -12
- package/dist/array/impl/array-utils-slice-clamped.mjs.map +1 -1
- package/dist/array/impl/array-utils-slicing.d.mts.map +1 -1
- package/dist/array/impl/array-utils-slicing.mjs +44 -96
- package/dist/array/impl/array-utils-slicing.mjs.map +1 -1
- package/dist/array/impl/array-utils-transformation.d.mts +4 -4
- package/dist/array/impl/array-utils-transformation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-transformation.mjs +150 -292
- package/dist/array/impl/array-utils-transformation.mjs.map +1 -1
- package/dist/array/impl/array-utils-validation.d.mts +17 -17
- package/dist/array/impl/array-utils-validation.d.mts.map +1 -1
- package/dist/array/impl/array-utils-validation.mjs +23 -174
- package/dist/array/impl/array-utils-validation.mjs.map +1 -1
- package/dist/array/impl/index.mjs +1 -1
- package/dist/collections/imap-mapped.d.mts.map +1 -1
- package/dist/collections/imap-mapped.mjs +243 -330
- package/dist/collections/imap-mapped.mjs.map +1 -1
- package/dist/collections/imap.d.mts.map +1 -1
- package/dist/collections/imap.mjs +190 -275
- package/dist/collections/imap.mjs.map +1 -1
- package/dist/collections/iset-mapped.d.mts +1 -1
- package/dist/collections/iset-mapped.d.mts.map +1 -1
- package/dist/collections/iset-mapped.mjs +222 -444
- package/dist/collections/iset-mapped.mjs.map +1 -1
- package/dist/collections/iset.d.mts +1 -1
- package/dist/collections/iset.d.mts.map +1 -1
- package/dist/collections/iset.mjs +158 -324
- package/dist/collections/iset.mjs.map +1 -1
- package/dist/collections/queue.d.mts.map +1 -1
- package/dist/collections/queue.mjs +106 -178
- package/dist/collections/queue.mjs.map +1 -1
- package/dist/collections/stack.d.mts.map +1 -1
- package/dist/collections/stack.mjs +95 -165
- package/dist/collections/stack.mjs.map +1 -1
- package/dist/entry-point.mjs +2 -0
- package/dist/entry-point.mjs.map +1 -1
- package/dist/expect-type.d.mts +1 -1
- package/dist/expect-type.d.mts.map +1 -1
- package/dist/expect-type.mjs +1 -69
- package/dist/expect-type.mjs.map +1 -1
- package/dist/functional/match.mjs +9 -9
- package/dist/functional/match.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-expect-to-be.mjs +13 -14
- package/dist/functional/optional/impl/optional-expect-to-be.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-filter.mjs +14 -15
- package/dist/functional/optional/impl/optional-filter.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-flat-map.mjs +10 -11
- package/dist/functional/optional/impl/optional-flat-map.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-from-nullable.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-from-nullable.mjs +1 -25
- package/dist/functional/optional/impl/optional-from-nullable.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-is-none.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-is-none.mjs +0 -19
- package/dist/functional/optional/impl/optional-is-none.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-is-optional.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-is-optional.mjs +1 -23
- package/dist/functional/optional/impl/optional-is-optional.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-is-some.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-is-some.mjs +0 -20
- package/dist/functional/optional/impl/optional-is-some.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-map.mjs +13 -14
- package/dist/functional/optional/impl/optional-map.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-none.mjs +0 -16
- package/dist/functional/optional/impl/optional-none.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-or-else.mjs +10 -11
- package/dist/functional/optional/impl/optional-or-else.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-some.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-some.mjs +2 -21
- package/dist/functional/optional/impl/optional-some.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-to-nullable.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-to-nullable.mjs +1 -27
- package/dist/functional/optional/impl/optional-to-nullable.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-unwrap-or.mjs +9 -10
- package/dist/functional/optional/impl/optional-unwrap-or.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-unwrap-throw.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-unwrap-throw.mjs +4 -32
- package/dist/functional/optional/impl/optional-unwrap-throw.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-unwrap.mjs +4 -4
- package/dist/functional/optional/impl/optional-unwrap.mjs.map +1 -1
- package/dist/functional/optional/impl/optional-zip.d.mts.map +1 -1
- package/dist/functional/optional/impl/optional-zip.mjs +1 -35
- package/dist/functional/optional/impl/optional-zip.mjs.map +1 -1
- package/dist/functional/optional/impl/tag.mjs +2 -3
- package/dist/functional/optional/impl/tag.mjs.map +1 -1
- package/dist/functional/pipe.d.mts.map +1 -1
- package/dist/functional/pipe.mjs +9 -34
- package/dist/functional/pipe.mjs.map +1 -1
- package/dist/functional/result/impl/result-err.d.mts.map +1 -1
- package/dist/functional/result/impl/result-err.mjs +2 -27
- package/dist/functional/result/impl/result-err.mjs.map +1 -1
- package/dist/functional/result/impl/result-expect-to-be.mjs +13 -15
- package/dist/functional/result/impl/result-expect-to-be.mjs.map +1 -1
- package/dist/functional/result/impl/result-flat-map.mjs +16 -16
- package/dist/functional/result/impl/result-flat-map.mjs.map +1 -1
- package/dist/functional/result/impl/result-fold.mjs +16 -16
- package/dist/functional/result/impl/result-fold.mjs.map +1 -1
- package/dist/functional/result/impl/result-from-promise.d.mts.map +1 -1
- package/dist/functional/result/impl/result-from-promise.mjs +4 -31
- package/dist/functional/result/impl/result-from-promise.mjs.map +1 -1
- package/dist/functional/result/impl/result-from-throwable.d.mts.map +1 -1
- package/dist/functional/result/impl/result-from-throwable.mjs +8 -38
- package/dist/functional/result/impl/result-from-throwable.mjs.map +1 -1
- package/dist/functional/result/impl/result-is-err.d.mts.map +1 -1
- package/dist/functional/result/impl/result-is-err.mjs +0 -19
- package/dist/functional/result/impl/result-is-err.mjs.map +1 -1
- package/dist/functional/result/impl/result-is-ok.d.mts.map +1 -1
- package/dist/functional/result/impl/result-is-ok.mjs +0 -19
- package/dist/functional/result/impl/result-is-ok.mjs.map +1 -1
- package/dist/functional/result/impl/result-is-result.d.mts.map +1 -1
- package/dist/functional/result/impl/result-is-result.mjs +1 -23
- package/dist/functional/result/impl/result-is-result.mjs.map +1 -1
- package/dist/functional/result/impl/result-map-err.mjs +16 -16
- package/dist/functional/result/impl/result-map-err.mjs.map +1 -1
- package/dist/functional/result/impl/result-map.mjs +16 -16
- package/dist/functional/result/impl/result-map.mjs.map +1 -1
- package/dist/functional/result/impl/result-ok.d.mts.map +1 -1
- package/dist/functional/result/impl/result-ok.mjs +2 -27
- package/dist/functional/result/impl/result-ok.mjs.map +1 -1
- package/dist/functional/result/impl/result-or-else.mjs +10 -12
- package/dist/functional/result/impl/result-or-else.mjs.map +1 -1
- package/dist/functional/result/impl/result-swap.d.mts.map +1 -1
- package/dist/functional/result/impl/result-swap.mjs +4 -22
- package/dist/functional/result/impl/result-swap.mjs.map +1 -1
- package/dist/functional/result/impl/result-to-optional.d.mts.map +1 -1
- package/dist/functional/result/impl/result-to-optional.mjs +0 -27
- package/dist/functional/result/impl/result-to-optional.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-err-or.mjs +9 -11
- package/dist/functional/result/impl/result-unwrap-err-or.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-err-throw.d.mts.map +1 -1
- package/dist/functional/result/impl/result-unwrap-err-throw.mjs +13 -40
- package/dist/functional/result/impl/result-unwrap-err-throw.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-err.d.mts.map +1 -1
- package/dist/functional/result/impl/result-unwrap-err.mjs +4 -32
- package/dist/functional/result/impl/result-unwrap-err.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-ok-or.mjs +9 -11
- package/dist/functional/result/impl/result-unwrap-ok-or.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-ok.mjs +4 -4
- package/dist/functional/result/impl/result-unwrap-ok.mjs.map +1 -1
- package/dist/functional/result/impl/result-unwrap-throw.d.mts.map +1 -1
- package/dist/functional/result/impl/result-unwrap-throw.mjs +4 -35
- package/dist/functional/result/impl/result-unwrap-throw.mjs.map +1 -1
- package/dist/functional/result/impl/result-zip.d.mts.map +1 -1
- package/dist/functional/result/impl/result-zip.mjs +1 -34
- package/dist/functional/result/impl/result-zip.mjs.map +1 -1
- package/dist/functional/result/impl/tag.mjs +2 -3
- package/dist/functional/result/impl/tag.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/tag.mjs +3 -5
- package/dist/functional/ternary-result/impl/tag.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-err.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-err.mjs +2 -15
- package/dist/functional/ternary-result/impl/ternary-result-err.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs +13 -13
- package/dist/functional/ternary-result/impl/ternary-result-expect-to-be.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs +27 -26
- package/dist/functional/ternary-result/impl/ternary-result-flat-map.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-fold.mjs +21 -22
- package/dist/functional/ternary-result/impl/ternary-result-fold.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs +4 -20
- package/dist/functional/ternary-result/impl/ternary-result-from-promise.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs +7 -25
- package/dist/functional/ternary-result/impl/ternary-result-from-throwable.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-err.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs +0 -17
- package/dist/functional/ternary-result/impl/ternary-result-is-err.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs +0 -19
- package/dist/functional/ternary-result/impl/ternary-result-is-ok.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs +1 -25
- package/dist/functional/ternary-result/impl/ternary-result-is-ternary-result.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs +0 -18
- package/dist/functional/ternary-result/impl/ternary-result-is-warn.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs +13 -15
- package/dist/functional/ternary-result/impl/ternary-result-map-err.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs +18 -18
- package/dist/functional/ternary-result/impl/ternary-result-map-warn.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-map.mjs +21 -22
- package/dist/functional/ternary-result/impl/ternary-result-map.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-ok.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-ok.mjs +2 -16
- package/dist/functional/ternary-result/impl/ternary-result-ok.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs +9 -9
- package/dist/functional/ternary-result/impl/ternary-result-or-else.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs +4 -22
- package/dist/functional/ternary-result/impl/ternary-result-to-optional.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs +9 -9
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-or.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs +12 -27
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err-throw.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs +4 -19
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-err.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs +9 -9
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok-or.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs +4 -5
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-ok.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs +15 -27
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-throw.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs +9 -9
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-or.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs +10 -24
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn-throw.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs +4 -19
- package/dist/functional/ternary-result/impl/ternary-result-unwrap-warn.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-warn.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-warn.mjs +3 -19
- package/dist/functional/ternary-result/impl/ternary-result-warn.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-zip.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/ternary-result-zip.mjs +14 -45
- package/dist/functional/ternary-result/impl/ternary-result-zip.mjs.map +1 -1
- package/dist/functional/ternary-result/impl/variant-name.d.mts +1 -1
- package/dist/functional/ternary-result/impl/variant-name.d.mts.map +1 -1
- package/dist/functional/ternary-result/impl/variant-name.mjs +8 -9
- package/dist/functional/ternary-result/impl/variant-name.mjs.map +1 -1
- package/dist/guard/as-length-bounded-array.d.mts +117 -0
- package/dist/guard/as-length-bounded-array.d.mts.map +1 -0
- package/dist/guard/as-length-bounded-array.mjs +37 -0
- package/dist/guard/as-length-bounded-array.mjs.map +1 -0
- package/dist/guard/has-key.d.mts.map +1 -1
- package/dist/guard/has-key.mjs +0 -41
- package/dist/guard/has-key.mjs.map +1 -1
- package/dist/guard/index.d.mts +2 -0
- package/dist/guard/index.d.mts.map +1 -1
- package/dist/guard/index.mjs +2 -0
- package/dist/guard/index.mjs.map +1 -1
- package/dist/guard/is-length-bounded-array.d.mts +159 -0
- package/dist/guard/is-length-bounded-array.d.mts.map +1 -0
- package/dist/guard/is-length-bounded-array.mjs +7 -0
- package/dist/guard/is-length-bounded-array.mjs.map +1 -0
- package/dist/guard/is-length-bounded-string.d.mts +5 -6
- package/dist/guard/is-length-bounded-string.d.mts.map +1 -1
- package/dist/guard/is-length-bounded-string.mjs +0 -157
- package/dist/guard/is-length-bounded-string.mjs.map +1 -1
- package/dist/guard/is-non-empty-string.d.mts +1 -1
- package/dist/guard/is-non-empty-string.d.mts.map +1 -1
- package/dist/guard/is-non-empty-string.mjs +1 -38
- package/dist/guard/is-non-empty-string.mjs.map +1 -1
- package/dist/guard/is-non-null-object.d.mts.map +1 -1
- package/dist/guard/is-non-null-object.mjs +1 -35
- package/dist/guard/is-non-null-object.mjs.map +1 -1
- package/dist/guard/is-primitive.d.mts.map +1 -1
- package/dist/guard/is-primitive.mjs +12 -43
- package/dist/guard/is-primitive.mjs.map +1 -1
- package/dist/guard/is-record.d.mts.map +1 -1
- package/dist/guard/is-record.mjs +0 -86
- package/dist/guard/is-record.mjs.map +1 -1
- package/dist/guard/is-type.d.mts.map +1 -1
- package/dist/guard/is-type.mjs +12 -399
- package/dist/guard/is-type.mjs.map +1 -1
- package/dist/guard/key-is-in.d.mts.map +1 -1
- package/dist/guard/key-is-in.mjs +0 -40
- package/dist/guard/key-is-in.mjs.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -1
- package/dist/iterator/range.mjs +16 -16
- package/dist/iterator/range.mjs.map +1 -1
- package/dist/json/json.d.mts.map +1 -1
- package/dist/json/json.mjs +52 -340
- package/dist/json/json.mjs.map +1 -1
- package/dist/number/branded-types/finite-number.d.mts +3 -3
- package/dist/number/branded-types/finite-number.mjs +135 -154
- package/dist/number/branded-types/finite-number.mjs.map +1 -1
- package/dist/number/branded-types/int.d.mts +4 -4
- package/dist/number/branded-types/int.mjs +205 -245
- package/dist/number/branded-types/int.mjs.map +1 -1
- package/dist/number/branded-types/int16.d.mts +15 -15
- package/dist/number/branded-types/int16.mjs +116 -123
- package/dist/number/branded-types/int16.mjs.map +1 -1
- package/dist/number/branded-types/int32.d.mts +11 -11
- package/dist/number/branded-types/int32.mjs +116 -123
- package/dist/number/branded-types/int32.mjs.map +1 -1
- package/dist/number/branded-types/negative-finite-number.d.mts +4 -4
- package/dist/number/branded-types/negative-finite-number.mjs +129 -144
- package/dist/number/branded-types/negative-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/negative-int.d.mts +5 -5
- package/dist/number/branded-types/negative-int.mjs +94 -113
- package/dist/number/branded-types/negative-int.mjs.map +1 -1
- package/dist/number/branded-types/negative-safe-int.d.mts +5 -5
- package/dist/number/branded-types/negative-safe-int.mjs +103 -124
- package/dist/number/branded-types/negative-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-finite-number.d.mts +5 -5
- package/dist/number/branded-types/non-negative-finite-number.mjs +136 -142
- package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-int16.d.mts +16 -16
- package/dist/number/branded-types/non-negative-int16.mjs +109 -118
- package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-int32.d.mts +12 -12
- package/dist/number/branded-types/non-negative-int32.mjs +110 -119
- package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-finite-number.d.mts +3 -3
- package/dist/number/branded-types/non-positive-finite-number.mjs +120 -124
- package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-int.d.mts +4 -4
- package/dist/number/branded-types/non-positive-int.mjs +167 -212
- package/dist/number/branded-types/non-positive-int.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-safe-int.d.mts +4 -4
- package/dist/number/branded-types/non-positive-safe-int.mjs +95 -106
- package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-finite-number.d.mts +4 -4
- package/dist/number/branded-types/non-zero-finite-number.mjs +114 -123
- package/dist/number/branded-types/non-zero-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int.d.mts +2 -2
- package/dist/number/branded-types/non-zero-int.mjs +72 -83
- package/dist/number/branded-types/non-zero-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int16.d.mts +7 -7
- package/dist/number/branded-types/non-zero-int16.mjs +96 -107
- package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int32.d.mts +5 -5
- package/dist/number/branded-types/non-zero-int32.mjs +97 -108
- package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-safe-int.d.mts +2 -2
- package/dist/number/branded-types/non-zero-safe-int.mjs +100 -111
- package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint16.d.mts +8 -8
- package/dist/number/branded-types/non-zero-uint16.mjs +96 -107
- package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint32.d.mts +6 -6
- package/dist/number/branded-types/non-zero-uint32.mjs +96 -107
- package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
- package/dist/number/branded-types/positive-finite-number.d.mts +8 -8
- package/dist/number/branded-types/positive-finite-number.mjs +139 -141
- package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/positive-int.d.mts +11 -11
- package/dist/number/branded-types/positive-int.mjs +228 -271
- package/dist/number/branded-types/positive-int.mjs.map +1 -1
- package/dist/number/branded-types/positive-int16.d.mts +19 -19
- package/dist/number/branded-types/positive-int16.mjs +109 -118
- package/dist/number/branded-types/positive-int16.mjs.map +1 -1
- package/dist/number/branded-types/positive-int32.d.mts +15 -15
- package/dist/number/branded-types/positive-int32.mjs +109 -118
- package/dist/number/branded-types/positive-int32.mjs.map +1 -1
- package/dist/number/branded-types/positive-safe-int.d.mts +11 -11
- package/dist/number/branded-types/positive-safe-int.mjs +244 -275
- package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/positive-uint16.d.mts +17 -17
- package/dist/number/branded-types/positive-uint16.mjs +109 -118
- package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
- package/dist/number/branded-types/positive-uint32.d.mts +13 -13
- package/dist/number/branded-types/positive-uint32.mjs +110 -119
- package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
- package/dist/number/branded-types/safe-int.d.mts +4 -4
- package/dist/number/branded-types/safe-int.mjs +251 -292
- package/dist/number/branded-types/safe-int.mjs.map +1 -1
- package/dist/number/branded-types/safe-uint.d.mts +8 -8
- package/dist/number/branded-types/safe-uint.mjs +111 -119
- package/dist/number/branded-types/safe-uint.mjs.map +1 -1
- package/dist/number/branded-types/uint.d.mts +8 -8
- package/dist/number/branded-types/uint.mjs +198 -225
- package/dist/number/branded-types/uint.mjs.map +1 -1
- package/dist/number/branded-types/uint16.d.mts +14 -14
- package/dist/number/branded-types/uint16.mjs +109 -119
- package/dist/number/branded-types/uint16.mjs.map +1 -1
- package/dist/number/branded-types/uint32.d.mts +10 -10
- package/dist/number/branded-types/uint32.mjs +110 -117
- package/dist/number/branded-types/uint32.mjs.map +1 -1
- package/dist/number/enum/int8.mjs +119 -145
- package/dist/number/enum/int8.mjs.map +1 -1
- package/dist/number/enum/uint8.mjs +107 -121
- package/dist/number/enum/uint8.mjs.map +1 -1
- package/dist/number/num.d.mts +2 -2
- package/dist/number/num.d.mts.map +1 -1
- package/dist/number/num.mjs +76 -537
- package/dist/number/num.mjs.map +1 -1
- package/dist/number/refined-number-utils.d.mts +1 -1
- package/dist/number/refined-number-utils.d.mts.map +1 -1
- package/dist/number/refined-number-utils.mjs +127 -263
- package/dist/number/refined-number-utils.mjs.map +1 -1
- package/dist/object/object.d.mts.map +1 -1
- package/dist/object/object.mjs +107 -222
- package/dist/object/object.mjs.map +1 -1
- package/dist/others/cast-mutable.d.mts.map +1 -1
- package/dist/others/cast-mutable.mjs +8 -37
- package/dist/others/cast-mutable.mjs.map +1 -1
- package/dist/others/cast-readonly.d.mts.map +1 -1
- package/dist/others/cast-readonly.mjs +8 -36
- package/dist/others/cast-readonly.mjs.map +1 -1
- package/dist/others/debounce-function.d.mts.map +1 -1
- package/dist/others/debounce-function.mjs +7 -16
- package/dist/others/debounce-function.mjs.map +1 -1
- package/dist/others/fast-deep-equal.d.mts.map +1 -1
- package/dist/others/fast-deep-equal.mjs +43 -59
- package/dist/others/fast-deep-equal.mjs.map +1 -1
- package/dist/others/if-then.d.mts.map +1 -1
- package/dist/others/if-then.mjs +0 -29
- package/dist/others/if-then.mjs.map +1 -1
- package/dist/others/map-nullable.mjs +9 -9
- package/dist/others/map-nullable.mjs.map +1 -1
- package/dist/others/memoize-function.mjs +12 -12
- package/dist/others/memoize-function.mjs.map +1 -1
- package/dist/others/tuple.d.mts.map +1 -1
- package/dist/others/tuple.mjs +0 -50
- package/dist/others/tuple.mjs.map +1 -1
- package/dist/others/unknown-to-string.d.mts.map +1 -1
- package/dist/others/unknown-to-string.mjs +41 -88
- package/dist/others/unknown-to-string.mjs.map +1 -1
- package/dist/promise/promise.d.mts.map +1 -1
- package/dist/promise/promise.mjs +4 -49
- package/dist/promise/promise.mjs.map +1 -1
- package/package.json +14 -13
- package/src/array/impl/array-utils-creation.mts +3 -3
- package/src/array/impl/array-utils-modification.mts +7 -7
- package/src/array/impl/array-utils-modification.test.mts +4 -4
- package/src/array/impl/array-utils-transformation.mts +4 -4
- package/src/array/impl/array-utils-transformation.test.mts +7 -7
- package/src/array/impl/array-utils-validation.mts +24 -24
- package/src/array/impl/array-utils-validation.test.mts +94 -92
- package/src/collections/queue.test.mts +1 -1
- package/src/guard/as-length-bounded-array.mts +190 -0
- package/src/guard/as-length-bounded-array.test.mts +118 -0
- package/src/guard/index.mts +2 -0
- package/src/guard/is-length-bounded-array.mts +195 -0
- package/src/guard/is-length-bounded-array.test.mts +169 -0
- package/src/guard/is-length-bounded-string.mts +6 -6
- package/src/object/object.test.mts +3 -3
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BoundedLengthArray,
|
|
3
|
+
type FixedLengthArray,
|
|
4
|
+
type MaxLengthArray,
|
|
5
|
+
type MinLengthArray,
|
|
6
|
+
} from 'ts-type-forge';
|
|
7
|
+
import { expectType } from '../expect-type.mjs';
|
|
8
|
+
import {
|
|
9
|
+
asBoundedLengthArray,
|
|
10
|
+
asFixedLengthArray,
|
|
11
|
+
asMaxLengthArray,
|
|
12
|
+
asMinLengthArray,
|
|
13
|
+
} from './as-length-bounded-array.mjs';
|
|
14
|
+
|
|
15
|
+
describe(asFixedLengthArray, () => {
|
|
16
|
+
test('should return the input when the length matches exactly', () => {
|
|
17
|
+
const xs: readonly number[] = [0, 1, 2, 3] as const;
|
|
18
|
+
|
|
19
|
+
const casted = asFixedLengthArray(xs, 4);
|
|
20
|
+
|
|
21
|
+
expect(casted).toBe(xs);
|
|
22
|
+
|
|
23
|
+
expectType<typeof casted, FixedLengthArray<4, number>>('<=');
|
|
24
|
+
|
|
25
|
+
// in-range indexed access does not include `undefined`
|
|
26
|
+
const _first = casted[0];
|
|
27
|
+
|
|
28
|
+
expectType<typeof _first, number>('=');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('should throw when the length does not match', () => {
|
|
32
|
+
expect(() => asFixedLengthArray([0, 1, 2], 4)).toThrow(TypeError);
|
|
33
|
+
|
|
34
|
+
expect(() => asFixedLengthArray([0, 1, 2], 4)).toThrow(
|
|
35
|
+
'Expected an array of length 4, got an array of length 3',
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('should preserve the original array type', () => {
|
|
40
|
+
const tuple = [1, 2, 3] as const;
|
|
41
|
+
|
|
42
|
+
const casted = asFixedLengthArray(tuple, 3);
|
|
43
|
+
|
|
44
|
+
expect(casted).toBe(tuple);
|
|
45
|
+
|
|
46
|
+
expectType<typeof casted, readonly [1, 2, 3]>('<=');
|
|
47
|
+
|
|
48
|
+
expectType<typeof casted, FixedLengthArray<3, 1 | 2 | 3>>('<=');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe(asMinLengthArray, () => {
|
|
53
|
+
test('should return the input when the array is long enough', () => {
|
|
54
|
+
const xs: readonly number[] = [0, 1, 2, 3] as const;
|
|
55
|
+
|
|
56
|
+
const casted = asMinLengthArray(xs, 3);
|
|
57
|
+
|
|
58
|
+
expect(casted).toBe(xs);
|
|
59
|
+
|
|
60
|
+
expectType<typeof casted, MinLengthArray<3, number>>('<=');
|
|
61
|
+
|
|
62
|
+
expectType<typeof casted, MinLengthArray<1, number>>('<='); // 3 >= 1
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('should throw when the array is too short', () => {
|
|
66
|
+
expect(() => asMinLengthArray([0], 3)).toThrow(TypeError);
|
|
67
|
+
|
|
68
|
+
expect(() => asMinLengthArray([0], 3)).toThrow(
|
|
69
|
+
'Expected an array of length >= 3, got an array of length 1',
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
describe(asMaxLengthArray, () => {
|
|
75
|
+
test('should return the input when the array is short enough', () => {
|
|
76
|
+
const xs: readonly number[] = [0, 1, 2] as const;
|
|
77
|
+
|
|
78
|
+
const casted = asMaxLengthArray(xs, 8);
|
|
79
|
+
|
|
80
|
+
expect(casted).toBe(xs);
|
|
81
|
+
|
|
82
|
+
expectType<typeof casted, MaxLengthArray<8, number>>('<=');
|
|
83
|
+
|
|
84
|
+
expectType<typeof casted, MaxLengthArray<16, number>>('<='); // 8 <= 16
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('should throw when the array is too long', () => {
|
|
88
|
+
expect(() => asMaxLengthArray([0, 1, 2], 2)).toThrow(TypeError);
|
|
89
|
+
|
|
90
|
+
expect(() => asMaxLengthArray([0, 1, 2], 2)).toThrow(
|
|
91
|
+
'Expected an array of length <= 2, got an array of length 3',
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe(asBoundedLengthArray, () => {
|
|
97
|
+
test('should return the input when the length is within the range', () => {
|
|
98
|
+
const xs: readonly number[] = [1, 2, 3] as const;
|
|
99
|
+
|
|
100
|
+
const casted = asBoundedLengthArray(xs, 1, 5);
|
|
101
|
+
|
|
102
|
+
expect(casted).toBe(xs);
|
|
103
|
+
|
|
104
|
+
expectType<typeof casted, BoundedLengthArray<1, 5, number>>('<=');
|
|
105
|
+
|
|
106
|
+
expectType<typeof casted, MinLengthArray<1, number>>('<=');
|
|
107
|
+
|
|
108
|
+
expectType<typeof casted, MaxLengthArray<5, number>>('<=');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('should throw when the length is out of the range', () => {
|
|
112
|
+
expect(() => asBoundedLengthArray([], 1, 5)).toThrow(TypeError);
|
|
113
|
+
|
|
114
|
+
expect(() => asBoundedLengthArray([1, 2, 3, 4, 5, 6], 1, 5)).toThrow(
|
|
115
|
+
'Expected an array of length in [1, 5], got an array of length 6',
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
package/src/guard/index.mts
CHANGED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BoundedLengthArray,
|
|
3
|
+
type FixedLengthArray,
|
|
4
|
+
type MaxLengthArray,
|
|
5
|
+
type MinLengthArray,
|
|
6
|
+
type SupportedLength,
|
|
7
|
+
} from 'ts-type-forge';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Type guard that checks if an array has at least `minLength` elements.
|
|
11
|
+
*
|
|
12
|
+
* **Type Narrowing Behavior:**
|
|
13
|
+
*
|
|
14
|
+
* - Narrows the input to `MinLengthArray<MinLength, E>` while preserving the
|
|
15
|
+
* original array type (e.g. tuple types) via intersection.
|
|
16
|
+
* - The length constraint lives only in the brand, so this stays cheap for the
|
|
17
|
+
* type checker even when the element type is large — unlike
|
|
18
|
+
* `isMinLengthTuple`, which narrows to a structural tuple type.
|
|
19
|
+
* - The result participates in the length-constraint subtyping relation: for
|
|
20
|
+
* example, a value narrowed to `MinLengthArray<3, E>` is assignable to
|
|
21
|
+
* `MinLengthArray<1, E>`.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* const input: readonly number[] = [0, 1, 2, 3];
|
|
27
|
+
*
|
|
28
|
+
* assert.isTrue(isMinLengthArray(input, 3));
|
|
29
|
+
*
|
|
30
|
+
* assert.isFalse(isMinLengthArray([0], 3));
|
|
31
|
+
*
|
|
32
|
+
* if (isMinLengthArray(input, 3)) {
|
|
33
|
+
* const history: MinLengthArray<3, number> = input;
|
|
34
|
+
*
|
|
35
|
+
* const nonEmpty: MinLengthArray<1, number> = input; // OK (3 >= 1)
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @template Xs - The input array type (tuple types are preserved).
|
|
40
|
+
* @template MinLength - The minimum number of elements (inclusive).
|
|
41
|
+
* @param xs - The array to check.
|
|
42
|
+
* @param minLength - The minimum number of elements (inclusive).
|
|
43
|
+
* @returns `true` if `xs.length >= minLength`, `false` otherwise. When `true`,
|
|
44
|
+
* TypeScript narrows `xs` to `MinLengthArray<MinLength, Xs[number]> & Xs`.
|
|
45
|
+
*/
|
|
46
|
+
export const isMinLengthArray = <
|
|
47
|
+
Xs extends readonly unknown[],
|
|
48
|
+
MinLength extends SupportedLength,
|
|
49
|
+
>(
|
|
50
|
+
xs: Xs,
|
|
51
|
+
minLength: MinLength,
|
|
52
|
+
): xs is MinLengthArray<MinLength, Xs[number]> & Xs => xs.length >= minLength;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Type guard that checks if an array has at most `maxLength` elements.
|
|
56
|
+
*
|
|
57
|
+
* **Type Narrowing Behavior:**
|
|
58
|
+
*
|
|
59
|
+
* - Narrows the input to `MaxLengthArray<MaxLength, E>` while preserving the
|
|
60
|
+
* original array type (e.g. tuple types) via intersection.
|
|
61
|
+
* - The length constraint lives only in the brand, so this stays cheap for the
|
|
62
|
+
* type checker even when the element type is large — unlike
|
|
63
|
+
* `isMaxLengthTuple`, which narrows to a union of tuple types.
|
|
64
|
+
* - The result participates in the length-constraint subtyping relation: for
|
|
65
|
+
* example, a value narrowed to `MaxLengthArray<8, E>` is assignable to
|
|
66
|
+
* `MaxLengthArray<16, E>`.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* const input: readonly string[] = ['a', 'b', 'c'];
|
|
72
|
+
*
|
|
73
|
+
* assert.isTrue(isMaxLengthArray(input, 8));
|
|
74
|
+
*
|
|
75
|
+
* assert.isFalse(isMaxLengthArray(input, 2));
|
|
76
|
+
*
|
|
77
|
+
* if (isMaxLengthArray(input, 8)) {
|
|
78
|
+
* const tags: MaxLengthArray<8, string> = input;
|
|
79
|
+
*
|
|
80
|
+
* const relaxed: MaxLengthArray<16, string> = input; // OK (8 <= 16)
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @template Xs - The input array type (tuple types are preserved).
|
|
85
|
+
* @template MaxLength - The maximum number of elements (inclusive).
|
|
86
|
+
* @param xs - The array to check.
|
|
87
|
+
* @param maxLength - The maximum number of elements (inclusive).
|
|
88
|
+
* @returns `true` if `xs.length <= maxLength`, `false` otherwise. When `true`,
|
|
89
|
+
* TypeScript narrows `xs` to `MaxLengthArray<MaxLength, Xs[number]> & Xs`.
|
|
90
|
+
*/
|
|
91
|
+
export const isMaxLengthArray = <
|
|
92
|
+
Xs extends readonly unknown[],
|
|
93
|
+
MaxLength extends SupportedLength,
|
|
94
|
+
>(
|
|
95
|
+
xs: Xs,
|
|
96
|
+
maxLength: MaxLength,
|
|
97
|
+
): xs is MaxLengthArray<MaxLength, Xs[number]> & Xs => xs.length <= maxLength;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Type guard that checks if an array's length is within the inclusive range
|
|
101
|
+
* `[minLength, maxLength]`.
|
|
102
|
+
*
|
|
103
|
+
* **Type Narrowing Behavior:**
|
|
104
|
+
*
|
|
105
|
+
* - Narrows the input to `BoundedLengthArray<MinLength, MaxLength, E>` while
|
|
106
|
+
* preserving the original array type (e.g. tuple types) via intersection.
|
|
107
|
+
* - Since `BoundedLengthArray` is the intersection of `MinLengthArray` and
|
|
108
|
+
* `MaxLengthArray`, the narrowed value is assignable to both, and both
|
|
109
|
+
* bounds can be weakened independently.
|
|
110
|
+
* - The length constraint lives only in the brand, so this stays cheap for the
|
|
111
|
+
* type checker even when the element type is large — unlike
|
|
112
|
+
* `isBoundedLengthTuple`, which narrows to a union of tuple types.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
*
|
|
116
|
+
* ```ts
|
|
117
|
+
* const input: readonly number[] = [1, 2, 3];
|
|
118
|
+
*
|
|
119
|
+
* assert.isTrue(isBoundedLengthArray(input, 1, 5));
|
|
120
|
+
*
|
|
121
|
+
* assert.isFalse(isBoundedLengthArray([], 1, 5));
|
|
122
|
+
*
|
|
123
|
+
* if (isBoundedLengthArray(input, 1, 5)) {
|
|
124
|
+
* const selection: BoundedLengthArray<1, 5, number> = input;
|
|
125
|
+
*
|
|
126
|
+
* const relaxed: BoundedLengthArray<0, 100, number> = input; // OK ([1, 5] ⊆ [0, 100])
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @template Xs - The input array type (tuple types are preserved).
|
|
131
|
+
* @template MinLength - The minimum number of elements (inclusive).
|
|
132
|
+
* @template MaxLength - The maximum number of elements (inclusive).
|
|
133
|
+
* @param xs - The array to check.
|
|
134
|
+
* @param minLength - The minimum number of elements (inclusive).
|
|
135
|
+
* @param maxLength - The maximum number of elements (inclusive).
|
|
136
|
+
* @returns `true` if `minLength <= xs.length && xs.length <= maxLength`,
|
|
137
|
+
* `false` otherwise. When `true`, TypeScript narrows `xs` to
|
|
138
|
+
* `BoundedLengthArray<MinLength, MaxLength, Xs[number]> & Xs`.
|
|
139
|
+
*/
|
|
140
|
+
export const isBoundedLengthArray = <
|
|
141
|
+
Xs extends readonly unknown[],
|
|
142
|
+
MinLength extends SupportedLength,
|
|
143
|
+
MaxLength extends SupportedLength,
|
|
144
|
+
>(
|
|
145
|
+
xs: Xs,
|
|
146
|
+
minLength: MinLength,
|
|
147
|
+
maxLength: MaxLength,
|
|
148
|
+
): xs is BoundedLengthArray<MinLength, MaxLength, Xs[number]> & Xs =>
|
|
149
|
+
xs.length >= minLength && xs.length <= maxLength;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Type guard that checks if an array has exactly `length` elements.
|
|
153
|
+
*
|
|
154
|
+
* **Type Narrowing Behavior:**
|
|
155
|
+
*
|
|
156
|
+
* - Narrows the input to `FixedLengthArray<Length, E>` while preserving the
|
|
157
|
+
* original array type (e.g. tuple types) via intersection.
|
|
158
|
+
* - Since `FixedLengthArray<Length, E>` is defined as
|
|
159
|
+
* `BoundedLengthArray<Length, Length, E>`, the narrowed value is assignable
|
|
160
|
+
* to any `MinLengthArray<N, E>` with `N <= Length` and any
|
|
161
|
+
* `MaxLengthArray<N, E>` with `N >= Length`.
|
|
162
|
+
* - The length constraint lives only in the brand, so this stays cheap for the
|
|
163
|
+
* type checker even when the element type is large — unlike
|
|
164
|
+
* `isFixedLengthTuple`, which narrows to a structural tuple type.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
*
|
|
168
|
+
* ```ts
|
|
169
|
+
* const input: readonly number[] = [255, 128, 0];
|
|
170
|
+
*
|
|
171
|
+
* assert.isTrue(isFixedLengthArray(input, 3));
|
|
172
|
+
*
|
|
173
|
+
* assert.isFalse(isFixedLengthArray(input, 4));
|
|
174
|
+
*
|
|
175
|
+
* if (isFixedLengthArray(input, 3)) {
|
|
176
|
+
* const rgb: FixedLengthArray<3, number> = input;
|
|
177
|
+
*
|
|
178
|
+
* const atMost5: MaxLengthArray<5, number> = input; // OK (3 <= 5)
|
|
179
|
+
* }
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @template Xs - The input array type (tuple types are preserved).
|
|
183
|
+
* @template Length - The exact number of elements.
|
|
184
|
+
* @param xs - The array to check.
|
|
185
|
+
* @param length - The exact number of elements.
|
|
186
|
+
* @returns `true` if `xs.length === length`, `false` otherwise. When `true`,
|
|
187
|
+
* TypeScript narrows `xs` to `FixedLengthArray<Length, Xs[number]> & Xs`.
|
|
188
|
+
*/
|
|
189
|
+
export const isFixedLengthArray = <
|
|
190
|
+
Xs extends readonly unknown[],
|
|
191
|
+
Length extends SupportedLength,
|
|
192
|
+
>(
|
|
193
|
+
xs: Xs,
|
|
194
|
+
length: Length,
|
|
195
|
+
): xs is FixedLengthArray<Length, Xs[number]> & Xs => xs.length === length;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type BoundedLengthArray,
|
|
3
|
+
type FixedLengthArray,
|
|
4
|
+
type MaxLengthArray,
|
|
5
|
+
type MinLengthArray,
|
|
6
|
+
} from 'ts-type-forge';
|
|
7
|
+
import { expectType } from '../expect-type.mjs';
|
|
8
|
+
import {
|
|
9
|
+
isBoundedLengthArray,
|
|
10
|
+
isFixedLengthArray,
|
|
11
|
+
isMaxLengthArray,
|
|
12
|
+
isMinLengthArray,
|
|
13
|
+
} from './is-length-bounded-array.mjs';
|
|
14
|
+
|
|
15
|
+
describe(isMinLengthArray, () => {
|
|
16
|
+
test('should return true when the array is long enough', () => {
|
|
17
|
+
assert.isTrue(isMinLengthArray([1, 2, 3], 3));
|
|
18
|
+
|
|
19
|
+
assert.isTrue(isMinLengthArray([1, 2, 3], 2));
|
|
20
|
+
|
|
21
|
+
assert.isTrue(isMinLengthArray([], 0));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should return false when the array is too short', () => {
|
|
25
|
+
assert.isFalse(isMinLengthArray([1, 2], 3));
|
|
26
|
+
|
|
27
|
+
assert.isFalse(isMinLengthArray([], 1));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('should act as a type guard', () => {
|
|
31
|
+
const value: readonly number[] = [0, 1, 2, 3] as const;
|
|
32
|
+
|
|
33
|
+
if (isMinLengthArray(value, 3)) {
|
|
34
|
+
expectType<typeof value, MinLengthArray<3, number>>('<=');
|
|
35
|
+
|
|
36
|
+
expectType<typeof value, MinLengthArray<1, number>>('<='); // 3 >= 1
|
|
37
|
+
|
|
38
|
+
expectType<typeof value, MinLengthArray<5, number>>('!<=');
|
|
39
|
+
|
|
40
|
+
// indexed access below the minimum length does not include `undefined`
|
|
41
|
+
// (even under `noUncheckedIndexedAccess`)
|
|
42
|
+
const _first = value[0];
|
|
43
|
+
|
|
44
|
+
expectType<typeof _first, number>('=');
|
|
45
|
+
|
|
46
|
+
const _third = value[2];
|
|
47
|
+
|
|
48
|
+
expectType<typeof _third, number>('=');
|
|
49
|
+
|
|
50
|
+
const _fourth = value[3];
|
|
51
|
+
|
|
52
|
+
expectType<typeof _fourth, number | undefined>('=');
|
|
53
|
+
|
|
54
|
+
expect(value.length).toBeGreaterThanOrEqual(3);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should preserve the original array type', () => {
|
|
59
|
+
const tuple = [1, 2, 3] as const;
|
|
60
|
+
|
|
61
|
+
if (isMinLengthArray(tuple, 2)) {
|
|
62
|
+
expectType<typeof tuple, readonly [1, 2, 3]>('<=');
|
|
63
|
+
|
|
64
|
+
expectType<typeof tuple, MinLengthArray<2, 1 | 2 | 3>>('<=');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe(isMaxLengthArray, () => {
|
|
70
|
+
test('should return true when the array is short enough', () => {
|
|
71
|
+
assert.isTrue(isMaxLengthArray([1, 2, 3], 3));
|
|
72
|
+
|
|
73
|
+
assert.isTrue(isMaxLengthArray([1, 2, 3], 4));
|
|
74
|
+
|
|
75
|
+
assert.isTrue(isMaxLengthArray([], 0));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('should return false when the array is too long', () => {
|
|
79
|
+
assert.isFalse(isMaxLengthArray([1, 2, 3], 2));
|
|
80
|
+
|
|
81
|
+
assert.isFalse(isMaxLengthArray([1], 0));
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('should act as a type guard', () => {
|
|
85
|
+
const value: readonly number[] = [0, 1, 2] as const;
|
|
86
|
+
|
|
87
|
+
if (isMaxLengthArray(value, 8)) {
|
|
88
|
+
expectType<typeof value, MaxLengthArray<8, number>>('<=');
|
|
89
|
+
|
|
90
|
+
expectType<typeof value, MaxLengthArray<16, number>>('<='); // 8 <= 16
|
|
91
|
+
|
|
92
|
+
expectType<typeof value, MaxLengthArray<2, number>>('!<=');
|
|
93
|
+
|
|
94
|
+
expect(value.length).toBeLessThanOrEqual(8);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
describe(isBoundedLengthArray, () => {
|
|
100
|
+
test('should return true when the length is within the range', () => {
|
|
101
|
+
assert.isTrue(isBoundedLengthArray([1, 2, 3], 1, 5));
|
|
102
|
+
|
|
103
|
+
assert.isTrue(isBoundedLengthArray([1], 1, 5));
|
|
104
|
+
|
|
105
|
+
assert.isTrue(isBoundedLengthArray([1, 2, 3, 4, 5], 1, 5));
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('should return false when the length is out of the range', () => {
|
|
109
|
+
assert.isFalse(isBoundedLengthArray([], 1, 5));
|
|
110
|
+
|
|
111
|
+
assert.isFalse(isBoundedLengthArray([1, 2, 3, 4, 5, 6], 1, 5));
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should act as a type guard', () => {
|
|
115
|
+
const value: readonly number[] = [1, 2, 3] as const;
|
|
116
|
+
|
|
117
|
+
if (isBoundedLengthArray(value, 1, 5)) {
|
|
118
|
+
expectType<typeof value, BoundedLengthArray<1, 5, number>>('<=');
|
|
119
|
+
|
|
120
|
+
expectType<typeof value, BoundedLengthArray<0, 100, number>>('<=');
|
|
121
|
+
|
|
122
|
+
expectType<typeof value, MinLengthArray<1, number>>('<=');
|
|
123
|
+
|
|
124
|
+
expectType<typeof value, MaxLengthArray<5, number>>('<=');
|
|
125
|
+
|
|
126
|
+
expectType<typeof value, BoundedLengthArray<2, 5, number>>('!<=');
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe(isFixedLengthArray, () => {
|
|
132
|
+
test('should return true when the length matches exactly', () => {
|
|
133
|
+
assert.isTrue(isFixedLengthArray([1, 2, 3], 3));
|
|
134
|
+
|
|
135
|
+
assert.isTrue(isFixedLengthArray([], 0));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('should return false when the length does not match', () => {
|
|
139
|
+
assert.isFalse(isFixedLengthArray([1, 2, 3], 2));
|
|
140
|
+
|
|
141
|
+
assert.isFalse(isFixedLengthArray([1, 2, 3], 4));
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('should act as a type guard', () => {
|
|
145
|
+
const value: readonly number[] = [255, 128, 0] as const;
|
|
146
|
+
|
|
147
|
+
if (isFixedLengthArray(value, 3)) {
|
|
148
|
+
expectType<typeof value, FixedLengthArray<3, number>>('<=');
|
|
149
|
+
|
|
150
|
+
expectType<typeof value, MaxLengthArray<5, number>>('<='); // 3 <= 5
|
|
151
|
+
|
|
152
|
+
expectType<typeof value, MinLengthArray<1, number>>('<='); // 3 >= 1
|
|
153
|
+
|
|
154
|
+
expectType<typeof value, FixedLengthArray<4, number>>('!<=');
|
|
155
|
+
|
|
156
|
+
// `length` is narrowed to the literal and in-range indexed access does
|
|
157
|
+
// not include `undefined` (even under `noUncheckedIndexedAccess`)
|
|
158
|
+
const _len = value.length;
|
|
159
|
+
|
|
160
|
+
expectType<typeof _len, 3>('=');
|
|
161
|
+
|
|
162
|
+
const _second = value[1];
|
|
163
|
+
|
|
164
|
+
expectType<typeof _second, number>('=');
|
|
165
|
+
|
|
166
|
+
expect(value).toHaveLength(3);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
type FixedLengthString,
|
|
4
4
|
type MaxLengthString,
|
|
5
5
|
type MinLengthString,
|
|
6
|
+
type SupportedLength,
|
|
6
7
|
} from 'ts-type-forge';
|
|
7
|
-
import { type SizeType } from '../types.mjs';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Type guard that checks if a string has at least `minLength` characters.
|
|
@@ -46,7 +46,7 @@ import { type SizeType } from '../types.mjs';
|
|
|
46
46
|
*/
|
|
47
47
|
export const isMinLengthString = <
|
|
48
48
|
S extends string,
|
|
49
|
-
MinLength extends
|
|
49
|
+
MinLength extends SupportedLength,
|
|
50
50
|
>(
|
|
51
51
|
s: S,
|
|
52
52
|
minLength: MinLength,
|
|
@@ -92,7 +92,7 @@ export const isMinLengthString = <
|
|
|
92
92
|
*/
|
|
93
93
|
export const isMaxLengthString = <
|
|
94
94
|
S extends string,
|
|
95
|
-
MaxLength extends
|
|
95
|
+
MaxLength extends SupportedLength,
|
|
96
96
|
>(
|
|
97
97
|
s: S,
|
|
98
98
|
maxLength: MaxLength,
|
|
@@ -142,8 +142,8 @@ export const isMaxLengthString = <
|
|
|
142
142
|
*/
|
|
143
143
|
export const isBoundedLengthString = <
|
|
144
144
|
S extends string,
|
|
145
|
-
MinLength extends
|
|
146
|
-
MaxLength extends
|
|
145
|
+
MinLength extends SupportedLength,
|
|
146
|
+
MaxLength extends SupportedLength,
|
|
147
147
|
>(
|
|
148
148
|
s: S,
|
|
149
149
|
minLength: MinLength,
|
|
@@ -192,7 +192,7 @@ export const isBoundedLengthString = <
|
|
|
192
192
|
*/
|
|
193
193
|
export const isFixedLengthString = <
|
|
194
194
|
S extends string,
|
|
195
|
-
Length extends
|
|
195
|
+
Length extends SupportedLength,
|
|
196
196
|
>(
|
|
197
197
|
s: S,
|
|
198
198
|
length: Length,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type ArrayOfLength,
|
|
3
2
|
type DeepReadonly,
|
|
3
|
+
type FixedLengthTuple,
|
|
4
4
|
type UnknownRecord,
|
|
5
5
|
} from 'ts-type-forge';
|
|
6
6
|
import { expectType } from '../expect-type.mjs';
|
|
@@ -407,7 +407,7 @@ describe('merge', () => {
|
|
|
407
407
|
test('type: MergeAll with fixed length typed array', () => {
|
|
408
408
|
type MyRecord = Readonly<{ x: number; y: string }>;
|
|
409
409
|
|
|
410
|
-
const records:
|
|
410
|
+
const records: FixedLengthTuple<3, MyRecord> = [
|
|
411
411
|
{ x: 1, y: 'a' },
|
|
412
412
|
{ x: 2, y: 'b' },
|
|
413
413
|
{ x: 3, y: 'c' },
|
|
@@ -438,7 +438,7 @@ describe('merge', () => {
|
|
|
438
438
|
test('type: MergeAll with fixed length typed array and optional properties', () => {
|
|
439
439
|
type RecordWithOptional = Readonly<{ x: number; y?: string }>;
|
|
440
440
|
|
|
441
|
-
const records:
|
|
441
|
+
const records: FixedLengthTuple<2, RecordWithOptional> = [
|
|
442
442
|
{ x: 1, y: 'a' },
|
|
443
443
|
{ x: 2 },
|
|
444
444
|
] as const;
|