type-plus 7.3.1 → 7.5.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 +146 -183
- package/cjs/any/any_type.d.ts +8 -8
- package/cjs/any/any_type.d.ts.map +1 -1
- package/cjs/array/array.at.d.ts +3 -1
- package/cjs/array/array.at.d.ts.map +1 -1
- package/cjs/array/array.entries.d.ts +4 -3
- package/cjs/array/array.entries.d.ts.map +1 -1
- package/cjs/array/array.find_last.d.ts +3 -1
- package/cjs/array/array.find_last.d.ts.map +1 -1
- package/cjs/array/array.some.d.ts +1 -1
- package/cjs/array/array.some.d.ts.map +1 -1
- package/cjs/array/array_plus.common_prop_keys.d.ts +27 -0
- package/cjs/array/array_plus.common_prop_keys.d.ts.map +1 -0
- package/cjs/array/array_plus.common_prop_keys.js +3 -0
- package/cjs/array/array_plus.common_prop_keys.js.map +1 -0
- package/cjs/array/{array.concat.d.ts → array_plus.concat.d.ts} +4 -1
- package/cjs/array/array_plus.concat.d.ts.map +1 -0
- package/cjs/array/array_plus.concat.js +3 -0
- package/cjs/array/array_plus.concat.js.map +1 -0
- package/cjs/array/array_plus.d.ts +7 -3
- package/cjs/array/array_plus.d.ts.map +1 -1
- package/cjs/array/array_plus.drop_match.d.ts +4 -0
- package/cjs/array/array_plus.drop_match.d.ts.map +1 -0
- package/cjs/array/array_plus.drop_match.js +3 -0
- package/cjs/array/array_plus.drop_match.js.map +1 -0
- package/cjs/array/array_plus.element_match.d.ts +44 -0
- package/cjs/array/array_plus.element_match.d.ts.map +1 -0
- package/cjs/array/array_plus.element_match.js +3 -0
- package/cjs/array/array_plus.element_match.js.map +1 -0
- package/cjs/array/array_plus.filter.d.ts +2 -0
- package/cjs/array/array_plus.filter.d.ts.map +1 -0
- package/cjs/array/array_plus.filter.js +3 -0
- package/cjs/array/array_plus.filter.js.map +1 -0
- package/cjs/array/array_plus.find.d.ts +57 -0
- package/cjs/array/array_plus.find.d.ts.map +1 -0
- package/cjs/array/array_plus.find.js +3 -0
- package/cjs/array/array_plus.find.js.map +1 -0
- package/cjs/array/array_plus.pad_start.d.ts +5 -0
- package/cjs/array/array_plus.pad_start.d.ts.map +1 -0
- package/cjs/array/array_plus.pad_start.js +3 -0
- package/cjs/array/array_plus.pad_start.js.map +1 -0
- package/cjs/array/array_type.d.ts +30 -12
- package/cjs/array/array_type.d.ts.map +1 -1
- package/cjs/array/filter.d.ts +24 -4
- package/cjs/array/filter.d.ts.map +1 -1
- package/cjs/array/find_first.d.ts +62 -0
- package/cjs/array/find_first.d.ts.map +1 -0
- package/cjs/array/{array.find.js → find_first.js} +1 -1
- package/cjs/array/find_first.js.map +1 -0
- package/cjs/array/head.d.ts +30 -1
- package/cjs/array/head.d.ts.map +1 -1
- package/cjs/array/intersect_of_props.d.ts +5 -3
- package/cjs/array/intersect_of_props.d.ts.map +1 -1
- package/cjs/array/last.d.ts +27 -2
- package/cjs/array/last.d.ts.map +1 -1
- package/cjs/array/literal_array.d.ts +5 -0
- package/cjs/array/literal_array.d.ts.map +1 -1
- package/cjs/array/literal_array.js +5 -0
- package/cjs/array/literal_array.js.map +1 -1
- package/cjs/array/pad_start.d.ts +5 -5
- package/cjs/array/pad_start.d.ts.map +1 -1
- package/cjs/array/reduce_while.d.ts +6 -0
- package/cjs/array/reduce_while.d.ts.map +1 -1
- package/cjs/array/reduce_while.js +6 -0
- package/cjs/array/reduce_while.js.map +1 -1
- package/cjs/array/reverse.d.ts +5 -0
- package/cjs/array/reverse.d.ts.map +1 -1
- package/cjs/array/union_of_props.d.ts +1 -1
- package/cjs/array/union_of_props.d.ts.map +1 -1
- package/cjs/assertion/assert_type.d.ts +4 -1
- package/cjs/assertion/assert_type.d.ts.map +1 -1
- package/cjs/assertion/assert_type.js.map +1 -1
- package/cjs/functional/compose.d.ts +2 -1
- package/cjs/functional/compose.d.ts.map +1 -1
- package/cjs/functional/compose.js.map +1 -1
- package/cjs/functional/context.d.ts.map +1 -1
- package/cjs/index.d.ts +22 -3
- package/cjs/index.d.ts.map +1 -1
- package/cjs/index.js +9 -3
- package/cjs/index.js.map +1 -1
- package/cjs/math/numeric_struct.d.ts +1 -1
- package/cjs/math/numeric_struct.d.ts.map +1 -1
- package/cjs/mix_types/any_or_never_type.d.ts +1 -1
- package/cjs/never/never_type.d.ts +11 -0
- package/cjs/never/never_type.d.ts.map +1 -1
- package/cjs/nodejs/isNodeError.d.ts.map +1 -1
- package/cjs/nominal/brand.d.ts.map +1 -1
- package/cjs/nominal/flavor.d.ts.map +1 -1
- package/cjs/object/index.d.ts +0 -1
- package/cjs/object/index.d.ts.map +1 -1
- package/cjs/object/index.js.map +1 -1
- package/cjs/testing/test_type.d.ts +277 -233
- package/cjs/testing/test_type.d.ts.map +1 -1
- package/cjs/testing/test_type.js.map +1 -1
- package/cjs/tuple/common_prop_keys.d.ts +34 -0
- package/cjs/tuple/common_prop_keys.d.ts.map +1 -0
- package/cjs/tuple/common_prop_keys.js.map +1 -0
- package/cjs/tuple/create_tuple.d.ts.map +1 -1
- package/cjs/tuple/drop.d.ts +91 -0
- package/cjs/tuple/drop.d.ts.map +1 -0
- package/cjs/{array → tuple}/drop.js +3 -1
- package/cjs/tuple/drop.js.map +1 -0
- package/{esm/array → cjs/tuple}/tail.d.ts +1 -1
- package/cjs/{array → tuple}/tail.d.ts.map +1 -1
- package/cjs/{array → tuple}/tail.js.map +1 -1
- package/cjs/tuple/tuple_plus.common_prop_keys.d.ts +28 -0
- package/cjs/tuple/tuple_plus.common_prop_keys.d.ts.map +1 -0
- package/cjs/tuple/tuple_plus.common_prop_keys.js +3 -0
- package/cjs/tuple/tuple_plus.common_prop_keys.js.map +1 -0
- package/cjs/tuple/tuple_plus.d.ts +5 -1
- package/cjs/tuple/tuple_plus.d.ts.map +1 -1
- package/cjs/tuple/tuple_plus.drop_match.d.ts +6 -0
- package/cjs/tuple/tuple_plus.drop_match.d.ts.map +1 -0
- package/cjs/tuple/tuple_plus.drop_match.js +3 -0
- package/cjs/tuple/tuple_plus.drop_match.js.map +1 -0
- package/cjs/tuple/tuple_plus.filter.d.ts +13 -0
- package/cjs/tuple/tuple_plus.filter.d.ts.map +1 -0
- package/cjs/tuple/tuple_plus.filter.js +3 -0
- package/cjs/tuple/tuple_plus.filter.js.map +1 -0
- package/cjs/tuple/tuple_plus.find.d.ts +64 -0
- package/cjs/tuple/tuple_plus.find.d.ts.map +1 -0
- package/cjs/tuple/tuple_plus.find.js +3 -0
- package/cjs/tuple/tuple_plus.find.js.map +1 -0
- package/cjs/tuple/tuple_plus.js +0 -15
- package/cjs/tuple/tuple_plus.js.map +1 -1
- package/cjs/tuple/tuple_plus.pad_start.d.ts +11 -5
- package/cjs/tuple/tuple_plus.pad_start.d.ts.map +1 -1
- package/cjs/tuple/tuple_type.d.ts +41 -23
- package/cjs/tuple/tuple_type.d.ts.map +1 -1
- package/cjs/union/union.d.ts +33 -0
- package/cjs/union/union.d.ts.map +1 -0
- package/cjs/{array/array.concat.js → union/union.js} +1 -1
- package/cjs/union/union.js.map +1 -0
- package/cjs/unknown/unknown_type.d.ts +12 -0
- package/cjs/unknown/unknown_type.d.ts.map +1 -1
- package/cjs/utils/options.d.ts +10 -0
- package/cjs/utils/options.d.ts.map +1 -0
- package/cjs/utils/options.js +3 -0
- package/cjs/utils/options.js.map +1 -0
- package/esm/any/any_type.d.ts +8 -8
- package/esm/any/any_type.d.ts.map +1 -1
- package/esm/array/array.at.d.ts +3 -1
- package/esm/array/array.at.d.ts.map +1 -1
- package/esm/array/array.entries.d.ts +4 -3
- package/esm/array/array.entries.d.ts.map +1 -1
- package/esm/array/array.find_last.d.ts +3 -1
- package/esm/array/array.find_last.d.ts.map +1 -1
- package/esm/array/array.some.d.ts +1 -1
- package/esm/array/array.some.d.ts.map +1 -1
- package/esm/array/array_plus.common_prop_keys.d.ts +27 -0
- package/esm/array/array_plus.common_prop_keys.d.ts.map +1 -0
- package/esm/array/array_plus.common_prop_keys.js +2 -0
- package/esm/array/array_plus.common_prop_keys.js.map +1 -0
- package/esm/array/{array.concat.d.ts → array_plus.concat.d.ts} +4 -1
- package/esm/array/array_plus.concat.d.ts.map +1 -0
- package/esm/array/array_plus.concat.js +2 -0
- package/esm/array/array_plus.concat.js.map +1 -0
- package/esm/array/array_plus.d.ts +7 -3
- package/esm/array/array_plus.d.ts.map +1 -1
- package/esm/array/array_plus.drop_match.d.ts +4 -0
- package/esm/array/array_plus.drop_match.d.ts.map +1 -0
- package/esm/array/array_plus.drop_match.js +2 -0
- package/esm/array/array_plus.drop_match.js.map +1 -0
- package/esm/array/array_plus.element_match.d.ts +44 -0
- package/esm/array/array_plus.element_match.d.ts.map +1 -0
- package/esm/array/array_plus.element_match.js +2 -0
- package/esm/array/array_plus.element_match.js.map +1 -0
- package/esm/array/array_plus.filter.d.ts +2 -0
- package/esm/array/array_plus.filter.d.ts.map +1 -0
- package/esm/array/array_plus.filter.js +2 -0
- package/esm/array/array_plus.filter.js.map +1 -0
- package/esm/array/array_plus.find.d.ts +57 -0
- package/esm/array/array_plus.find.d.ts.map +1 -0
- package/esm/array/array_plus.find.js +2 -0
- package/esm/array/array_plus.find.js.map +1 -0
- package/esm/array/array_plus.pad_start.d.ts +5 -0
- package/esm/array/array_plus.pad_start.d.ts.map +1 -0
- package/esm/array/array_plus.pad_start.js +2 -0
- package/esm/array/array_plus.pad_start.js.map +1 -0
- package/esm/array/array_type.d.ts +30 -12
- package/esm/array/array_type.d.ts.map +1 -1
- package/esm/array/filter.d.ts +24 -4
- package/esm/array/filter.d.ts.map +1 -1
- package/esm/array/find_first.d.ts +62 -0
- package/esm/array/find_first.d.ts.map +1 -0
- package/esm/array/find_first.js +2 -0
- package/esm/array/find_first.js.map +1 -0
- package/esm/array/head.d.ts +30 -1
- package/esm/array/head.d.ts.map +1 -1
- package/esm/array/intersect_of_props.d.ts +5 -3
- package/esm/array/intersect_of_props.d.ts.map +1 -1
- package/esm/array/last.d.ts +27 -2
- package/esm/array/last.d.ts.map +1 -1
- package/esm/array/literal_array.d.ts +5 -0
- package/esm/array/literal_array.d.ts.map +1 -1
- package/esm/array/literal_array.js +5 -0
- package/esm/array/literal_array.js.map +1 -1
- package/esm/array/pad_start.d.ts +5 -5
- package/esm/array/pad_start.d.ts.map +1 -1
- package/esm/array/reduce_while.d.ts +6 -0
- package/esm/array/reduce_while.d.ts.map +1 -1
- package/esm/array/reduce_while.js +6 -0
- package/esm/array/reduce_while.js.map +1 -1
- package/esm/array/reverse.d.ts +5 -0
- package/esm/array/reverse.d.ts.map +1 -1
- package/esm/array/union_of_props.d.ts +1 -1
- package/esm/array/union_of_props.d.ts.map +1 -1
- package/esm/assertion/assert_type.d.ts +4 -1
- package/esm/assertion/assert_type.d.ts.map +1 -1
- package/esm/assertion/assert_type.js.map +1 -1
- package/esm/functional/compose.d.ts +2 -1
- package/esm/functional/compose.d.ts.map +1 -1
- package/esm/functional/compose.js.map +1 -1
- package/esm/functional/context.d.ts.map +1 -1
- package/esm/index.d.ts +22 -3
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +4 -2
- package/esm/index.js.map +1 -1
- package/esm/math/numeric_struct.d.ts +1 -1
- package/esm/math/numeric_struct.d.ts.map +1 -1
- package/esm/mix_types/any_or_never_type.d.ts +1 -1
- package/esm/never/never_type.d.ts +11 -0
- package/esm/never/never_type.d.ts.map +1 -1
- package/esm/nodejs/isNodeError.d.ts.map +1 -1
- package/esm/nominal/brand.d.ts.map +1 -1
- package/esm/nominal/flavor.d.ts.map +1 -1
- package/esm/object/index.d.ts +0 -1
- package/esm/object/index.d.ts.map +1 -1
- package/esm/object/index.js.map +1 -1
- package/esm/testing/test_type.d.ts +277 -233
- package/esm/testing/test_type.d.ts.map +1 -1
- package/esm/testing/test_type.js.map +1 -1
- package/esm/tuple/common_prop_keys.d.ts +34 -0
- package/esm/tuple/common_prop_keys.d.ts.map +1 -0
- package/esm/tuple/common_prop_keys.js.map +1 -0
- package/esm/tuple/create_tuple.d.ts.map +1 -1
- package/esm/tuple/drop.d.ts +91 -0
- package/esm/tuple/drop.d.ts.map +1 -0
- package/esm/tuple/drop.js +9 -0
- package/esm/tuple/drop.js.map +1 -0
- package/{cjs/array → esm/tuple}/tail.d.ts +1 -1
- package/esm/{array → tuple}/tail.d.ts.map +1 -1
- package/esm/{array → tuple}/tail.js.map +1 -1
- package/esm/tuple/tuple_plus.common_prop_keys.d.ts +28 -0
- package/esm/tuple/tuple_plus.common_prop_keys.d.ts.map +1 -0
- package/esm/tuple/tuple_plus.common_prop_keys.js +2 -0
- package/esm/tuple/tuple_plus.common_prop_keys.js.map +1 -0
- package/esm/tuple/tuple_plus.d.ts +5 -1
- package/esm/tuple/tuple_plus.d.ts.map +1 -1
- package/esm/tuple/tuple_plus.drop_match.d.ts +6 -0
- package/esm/tuple/tuple_plus.drop_match.d.ts.map +1 -0
- package/esm/tuple/tuple_plus.drop_match.js +2 -0
- package/esm/tuple/tuple_plus.drop_match.js.map +1 -0
- package/esm/tuple/tuple_plus.filter.d.ts +13 -0
- package/esm/tuple/tuple_plus.filter.d.ts.map +1 -0
- package/esm/tuple/tuple_plus.filter.js +2 -0
- package/esm/tuple/tuple_plus.filter.js.map +1 -0
- package/esm/tuple/tuple_plus.find.d.ts +64 -0
- package/esm/tuple/tuple_plus.find.d.ts.map +1 -0
- package/esm/tuple/tuple_plus.find.js +2 -0
- package/esm/tuple/tuple_plus.find.js.map +1 -0
- package/esm/tuple/tuple_plus.js +1 -1
- package/esm/tuple/tuple_plus.js.map +1 -1
- package/esm/tuple/tuple_plus.pad_start.d.ts +11 -5
- package/esm/tuple/tuple_plus.pad_start.d.ts.map +1 -1
- package/esm/tuple/tuple_type.d.ts +41 -23
- package/esm/tuple/tuple_type.d.ts.map +1 -1
- package/esm/union/union.d.ts +33 -0
- package/esm/union/union.d.ts.map +1 -0
- package/esm/union/union.js +2 -0
- package/esm/union/union.js.map +1 -0
- package/esm/unknown/unknown_type.d.ts +12 -0
- package/esm/unknown/unknown_type.d.ts.map +1 -1
- package/esm/utils/options.d.ts +10 -0
- package/esm/utils/options.d.ts.map +1 -0
- package/esm/utils/options.js +2 -0
- package/esm/utils/options.js.map +1 -0
- package/package.json +12 -9
- package/ts/any/any_type.ts +8 -9
- package/ts/any/readme.md +71 -4
- package/ts/array/array.at.ts +3 -1
- package/ts/array/array.entries.ts +4 -2
- package/ts/array/array.find_last.ts +3 -1
- package/ts/array/array.some.ts +1 -1
- package/ts/array/array_plus.common_prop_keys.ts +35 -0
- package/ts/array/{array.concat.ts → array_plus.concat.ts} +3 -0
- package/ts/array/array_plus.drop_match.ts +16 -0
- package/ts/array/array_plus.element_match.ts +61 -0
- package/ts/array/array_plus.filter.ts +5 -0
- package/ts/array/array_plus.find.ts +71 -0
- package/ts/array/array_plus.pad_start.ts +13 -0
- package/ts/array/array_plus.ts +7 -3
- package/ts/array/array_type.ts +30 -12
- package/ts/array/filter.ts +27 -22
- package/ts/array/find_first.ts +71 -0
- package/ts/array/head.ts +40 -1
- package/ts/array/intersect_of_props.ts +7 -3
- package/ts/array/last.ts +36 -2
- package/ts/array/literal_array.ts +5 -0
- package/ts/array/pad_start.ts +6 -10
- package/ts/array/readme.md +297 -32
- package/ts/array/reduce_while.ts +6 -0
- package/ts/array/reverse.ts +5 -0
- package/ts/array/union_of_props.ts +1 -1
- package/ts/assertion/assert_type.ts +4 -1
- package/ts/assertion/readme.md +4 -3
- package/ts/functional/compose.ts +2 -1
- package/ts/functional/context.ts +1 -1
- package/ts/index.ts +22 -3
- package/ts/math/numeric_struct.ts +9 -9
- package/ts/mix_types/any_or_never_type.ts +1 -1
- package/ts/mix_types/readme.md +7 -1
- package/ts/never/never_type.ts +13 -0
- package/ts/nodejs/isNodeError.ts +13 -13
- package/ts/nominal/brand.ts +1 -1
- package/ts/nominal/flavor.ts +1 -1
- package/ts/object/index.ts +0 -1
- package/ts/testing/readme.md +30 -0
- package/ts/testing/test_type.ts +279 -234
- package/ts/tuple/common_prop_keys.ts +41 -0
- package/ts/tuple/create_tuple.ts +9 -9
- package/ts/tuple/drop.ts +125 -0
- package/ts/tuple/readme.md +263 -9
- package/ts/{array → tuple}/tail.ts +1 -1
- package/ts/tuple/tuple_plus.common_prop_keys.ts +47 -0
- package/ts/tuple/tuple_plus.drop_match.ts +20 -0
- package/ts/tuple/tuple_plus.filter.ts +29 -0
- package/ts/tuple/tuple_plus.find.ts +88 -0
- package/ts/tuple/tuple_plus.pad_start.ts +37 -21
- package/ts/tuple/tuple_plus.ts +5 -1
- package/ts/tuple/tuple_type.ts +67 -25
- package/ts/union/readme.md +81 -0
- package/ts/union/union.ts +37 -0
- package/ts/unknown/unknown_type.ts +13 -0
- package/ts/utils/options.ts +10 -0
- package/cjs/array/array.concat.d.ts.map +0 -1
- package/cjs/array/array.concat.js.map +0 -1
- package/cjs/array/array.find.d.ts +0 -21
- package/cjs/array/array.find.d.ts.map +0 -1
- package/cjs/array/array.find.js.map +0 -1
- package/cjs/array/common_prop_keys.d.ts +0 -11
- package/cjs/array/common_prop_keys.d.ts.map +0 -1
- package/cjs/array/common_prop_keys.js.map +0 -1
- package/cjs/array/drop.d.ts +0 -19
- package/cjs/array/drop.d.ts.map +0 -1
- package/cjs/array/drop.js.map +0 -1
- package/cjs/array/index.d.ts +0 -17
- package/cjs/array/index.d.ts.map +0 -1
- package/cjs/array/index.js +0 -33
- package/cjs/array/index.js.map +0 -1
- package/esm/array/array.concat.d.ts.map +0 -1
- package/esm/array/array.concat.js +0 -2
- package/esm/array/array.concat.js.map +0 -1
- package/esm/array/array.find.d.ts +0 -21
- package/esm/array/array.find.d.ts.map +0 -1
- package/esm/array/array.find.js +0 -2
- package/esm/array/array.find.js.map +0 -1
- package/esm/array/common_prop_keys.d.ts +0 -11
- package/esm/array/common_prop_keys.d.ts.map +0 -1
- package/esm/array/common_prop_keys.js.map +0 -1
- package/esm/array/drop.d.ts +0 -19
- package/esm/array/drop.d.ts.map +0 -1
- package/esm/array/drop.js +0 -7
- package/esm/array/drop.js.map +0 -1
- package/esm/array/index.d.ts +0 -17
- package/esm/array/index.d.ts.map +0 -1
- package/esm/array/index.js +0 -17
- package/esm/array/index.js.map +0 -1
- package/ts/array/array.find.ts +0 -32
- package/ts/array/common_prop_keys.ts +0 -18
- package/ts/array/drop.ts +0 -71
- package/ts/array/index.ts +0 -16
- /package/cjs/{array → tuple}/common_prop_keys.js +0 -0
- /package/cjs/{array → tuple}/tail.js +0 -0
- /package/esm/{array → tuple}/common_prop_keys.js +0 -0
- /package/esm/{array → tuple}/tail.js +0 -0
package/ts/tuple/drop.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { DropMatch as ArrayDropMatch } from '../array/array_plus.drop_match.js'
|
|
2
|
+
import type { DropMatch as TupleDropMatch } from './tuple_plus.drop_match.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* ⚗️ *transform*
|
|
6
|
+
* 🔢 *customizable*
|
|
7
|
+
*
|
|
8
|
+
* Drops the first entry in the tuple `T`.
|
|
9
|
+
*
|
|
10
|
+
* If the type is an array, the same array will be returned.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* type R = DropFirst<[1, 2, 3]> // [2, 3]
|
|
15
|
+
* type R = DropFirst<[string]> // []
|
|
16
|
+
* type R = DropFirst<[]> // []
|
|
17
|
+
* type R = DropFirst<string[]> // string[]
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @typeParam Options['caseArray'] Return type when `T` is `Array`.
|
|
21
|
+
* Default to `T`.
|
|
22
|
+
*
|
|
23
|
+
* @typeParam Options['caseEmptyTuple'] Return type when `T` is an empty tuple.
|
|
24
|
+
* Default to `[]`.
|
|
25
|
+
*/
|
|
26
|
+
export type DropFirst<
|
|
27
|
+
T extends unknown[],
|
|
28
|
+
Options extends DropFirst.Options = DropFirst.DefaultOptions<T>
|
|
29
|
+
> = number extends T['length']
|
|
30
|
+
? Options['caseArray']
|
|
31
|
+
: T['length'] extends 0
|
|
32
|
+
? Options['caseEmptyTuple']
|
|
33
|
+
: T['length'] extends 1
|
|
34
|
+
? []
|
|
35
|
+
: T extends [any, ...infer Tail]
|
|
36
|
+
? Tail
|
|
37
|
+
: never
|
|
38
|
+
|
|
39
|
+
export namespace DropFirst {
|
|
40
|
+
export interface Options {
|
|
41
|
+
caseArray?: unknown,
|
|
42
|
+
caseEmptyTuple?: unknown,
|
|
43
|
+
}
|
|
44
|
+
export interface DefaultOptions<T> {
|
|
45
|
+
caseArray: T,
|
|
46
|
+
caseEmptyTuple: []
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* ⚗️ *transform*
|
|
52
|
+
* 🔢 *customizable*
|
|
53
|
+
*
|
|
54
|
+
* Drops the last entry in the tuple `T`.
|
|
55
|
+
*
|
|
56
|
+
* If the type is an array, the same array will be returned.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* type R = DropLast<[1, 2, 3]> // [2, 3]
|
|
61
|
+
* type R = DropLast<[string]> // []
|
|
62
|
+
* type R = DropLast<[]> // []
|
|
63
|
+
* type R = DropLast<string[]> // string[]
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @typeParam Options['caseArray'] Return type when `T` is `Array`.
|
|
67
|
+
* Default to `T`.
|
|
68
|
+
*
|
|
69
|
+
* @typeParam Options['caseEmptyTuple'] Return type when `T` is an empty tuple.
|
|
70
|
+
* Default to `[]`.
|
|
71
|
+
*/
|
|
72
|
+
export type DropLast<
|
|
73
|
+
T extends unknown[],
|
|
74
|
+
Cases extends DropLast.Options = DropLast.DefaultOptions<T>
|
|
75
|
+
> = number extends T['length']
|
|
76
|
+
? Cases['caseArray']
|
|
77
|
+
: T['length'] extends 0
|
|
78
|
+
? Cases['caseEmptyTuple']
|
|
79
|
+
: T['length'] extends 1
|
|
80
|
+
? []
|
|
81
|
+
: T extends [...infer Heads, any]
|
|
82
|
+
? Heads
|
|
83
|
+
: never
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
export namespace DropLast {
|
|
87
|
+
export interface Options {
|
|
88
|
+
caseArray?: unknown,
|
|
89
|
+
caseEmptyTuple?: unknown,
|
|
90
|
+
}
|
|
91
|
+
export interface DefaultOptions<T> {
|
|
92
|
+
caseArray: T,
|
|
93
|
+
caseEmptyTuple: []
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* ⚗️ *transform*
|
|
100
|
+
*
|
|
101
|
+
* Drops entries matching `Criteria` in array or tuple `A`.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* type R = DropMatch<Array<string | undefined>, undefined> // string[]
|
|
106
|
+
* type R = DropMatch<Array<string>, string> // never[]
|
|
107
|
+
* type R = DropMatch<Array<1 | 2>, number> // never[]
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export type DropMatch<A extends Readonly<Array<unknown>>, Criteria> = number extends A['length']
|
|
111
|
+
? ArrayDropMatch<A, Criteria>
|
|
112
|
+
: TupleDropMatch<A, Criteria>
|
|
113
|
+
|
|
114
|
+
export type DropNull<A extends Array<any>> = DropMatch<A, null>
|
|
115
|
+
export type DropNullable<A extends Array<any>> = DropMatch<A, null | undefined>
|
|
116
|
+
export type DropUndefined<A extends Array<any>> = DropMatch<A, undefined>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* drop a particular value from an array.
|
|
120
|
+
*
|
|
121
|
+
* 💀 *deprecated* the type does not sufficiently cover the use cases.
|
|
122
|
+
*/
|
|
123
|
+
export function drop<A extends Readonly<unknown[]>, const C>(array: A, value: C): DropMatch<A, C> {
|
|
124
|
+
return array.filter(v => v !== value) as DropMatch<A, C>
|
|
125
|
+
}
|
package/ts/tuple/readme.md
CHANGED
|
@@ -1,25 +1,279 @@
|
|
|
1
1
|
# Tuple
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
In TypeScript, the type of an JavaScript array can be an [array](../array/readme.md) or a [tuple](#tuple).
|
|
4
|
+
|
|
5
|
+
A *tuple type* is an array with fixed number of entries.
|
|
6
|
+
Each entry in the *tuple* is specified explicitly.
|
|
4
7
|
|
|
5
8
|
## Type Checking
|
|
6
9
|
|
|
7
10
|
The `TupleType<T>` and friends are used to check if `T` is a tuple, excluding array.
|
|
8
11
|
|
|
12
|
+
### [TupleType](./tuple_type.ts#l21)
|
|
13
|
+
|
|
14
|
+
`TupleType<T, Then = T, Else = never, Cases = { never }>`
|
|
15
|
+
|
|
16
|
+
🌪️ *filter*
|
|
17
|
+
|
|
18
|
+
Filter `T` to ensure it is a tuple, excluding array.
|
|
19
|
+
|
|
9
20
|
```ts
|
|
10
21
|
import type { TupleType } from 'type-plus'
|
|
11
22
|
|
|
12
|
-
type R = TupleType<[]>
|
|
13
|
-
type R = TupleType<[1]>
|
|
23
|
+
type R = TupleType<[]> // []
|
|
24
|
+
type R = TupleType<[1]> // [1]
|
|
25
|
+
|
|
26
|
+
type R = TupleType<number[]> // never
|
|
27
|
+
type R = TupleType<string> // never
|
|
28
|
+
type R = TupleType<never> // never
|
|
29
|
+
type R = TupleType<unknown> // never
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Overridable cases:
|
|
33
|
+
|
|
34
|
+
- `never`: if `T` is `never`, it returns `Else`.
|
|
35
|
+
|
|
36
|
+
### [IsTuple](./array_type.ts#l47)
|
|
37
|
+
|
|
38
|
+
`IsTuple<T, Then = true, Else = false, Cases = { never }>`
|
|
39
|
+
|
|
40
|
+
🎭 *validate*
|
|
41
|
+
|
|
42
|
+
Validate that `T` is a tuple, excluding array.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import type { IsTuple } from 'type-plus'
|
|
46
|
+
|
|
47
|
+
type R = IsTuple<[]> // true
|
|
48
|
+
|
|
49
|
+
type R = IsTuple<number[]> // false
|
|
50
|
+
type R = IsTuple<string> // false
|
|
51
|
+
type R = IsTuple<never> // false
|
|
52
|
+
type R = IsTuple<unknown> // false
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Overridable cases:
|
|
56
|
+
|
|
57
|
+
- `never`: if `T` is `never`, it returns `Else`.
|
|
58
|
+
|
|
59
|
+
### [NotTupleType](./tuple_type.ts#l70)
|
|
60
|
+
|
|
61
|
+
`NotArrayType<T, Then = T, Else = never, Cases = { never }>`
|
|
62
|
+
|
|
63
|
+
🌪️ *filter*
|
|
64
|
+
|
|
65
|
+
Filter `T` to ensure it is not an tuple, excluding array.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import type { NotArrayType } from 'type-plus'
|
|
69
|
+
|
|
70
|
+
type R = NotTupleType<[]> // never
|
|
71
|
+
type R = NotTupleType<[1]> // never
|
|
72
|
+
|
|
73
|
+
type R = NotTupleType<number[]> // number[]
|
|
74
|
+
type R = NotTupleType<string> // string
|
|
75
|
+
type R = NotTupleType<never> // never
|
|
76
|
+
type R = NotTupleType<unknown> // unknown
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Overridable cases:
|
|
80
|
+
|
|
81
|
+
- `never`: if `T` is `never`, it returns `Else`.
|
|
82
|
+
|
|
83
|
+
### [IsNotTupleType](./tuple_type.ts#l92)
|
|
84
|
+
|
|
85
|
+
`IsNotTupleType<T, Then = true, Else = false, Cases = { never }>`
|
|
86
|
+
|
|
87
|
+
🎭 *validate*
|
|
88
|
+
|
|
89
|
+
Validate that `T` is not a tuple, excluding array.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import type { IsNotTupleType } from 'type-plus'
|
|
93
|
+
|
|
94
|
+
type R = IsNotTuple<[]> // false
|
|
95
|
+
type R = IsNotTuple<[1]> // false
|
|
96
|
+
|
|
97
|
+
type R = IsNotTuple<number[]> // true
|
|
98
|
+
type R = IsNotTuple<string> // true
|
|
99
|
+
type R = IsNotTuple<never> // true
|
|
100
|
+
type R = IsNotTuple<unknown> // true
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Overridable cases:
|
|
104
|
+
|
|
105
|
+
- `never`: if `T` is `never`, it returns `Else`.
|
|
106
|
+
|
|
107
|
+
## [CommonPropKeys](./common_prop_keys.ts#l22)
|
|
108
|
+
|
|
109
|
+
`CommonPropKeys<T extends Record[], Options = { caseNever }>`
|
|
110
|
+
|
|
111
|
+
⚗️ *transform*
|
|
112
|
+
🔢 *customizable*
|
|
113
|
+
|
|
114
|
+
Gets the common property keys of the elements in tuple or array `T`.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { CommonPropKeys } from 'type-plus'
|
|
118
|
+
|
|
119
|
+
type R = CommonPropKeys<[{ a: 1, c: 1 }, { b: 1, c: 2 }]> // 'c'
|
|
120
|
+
type R = CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
|
|
121
|
+
type R = CommonPropKeys<Array<{ a: 1, b: 1 } | { a: 1, c: 1 }>> // 'a'
|
|
122
|
+
type R = CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
|
|
123
|
+
type R = CommonPropKeys<never> // caseNever: never
|
|
124
|
+
|
|
125
|
+
// customization
|
|
126
|
+
type R = CommonPropKeys<never, { caseNever: 1 }> // 1
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## [DropFirst](./drop.ts#l26)
|
|
130
|
+
|
|
131
|
+
`DropFirst<T extends unknown[], Options = { caseArray, caseEmptyTuple }>`
|
|
132
|
+
|
|
133
|
+
⚗️ *transform*
|
|
134
|
+
🔢 *customizable*
|
|
135
|
+
|
|
136
|
+
Drops the first entry in the tuple `T`.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { DropFirst } from 'type-plus'
|
|
140
|
+
|
|
141
|
+
type R = DropFirst<[1, 2, 3]> // [2, 3]
|
|
142
|
+
type R = DropFirst<[string]> // []
|
|
143
|
+
type R = DropFirst<string[]> // caseArray: string[]
|
|
144
|
+
type R = DropFirst<[]> // caseEmptyTuple: []
|
|
145
|
+
|
|
146
|
+
// customization
|
|
147
|
+
type R = DropFirst<string[], { caseArray: 1 }> // 1
|
|
148
|
+
type R = DropFirst<[], { caseEmptyTuple: 1 }> // 1
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## [DropLast](./drop.ts#l72)
|
|
152
|
+
|
|
153
|
+
`DropLast<T extends unknown[], Options = { array, empty_tuple }>`
|
|
154
|
+
|
|
155
|
+
⚗️ *transform*
|
|
156
|
+
🔢 *customizable*
|
|
157
|
+
|
|
158
|
+
Drops the last entry in the tuple `T`.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { DropLast } from 'type-plus'
|
|
162
|
+
|
|
163
|
+
type R = DropLast<[1, 2, 3]> // [2, 3]
|
|
164
|
+
type R = DropLast<[string]> // []
|
|
165
|
+
type R = DropLast<string[]> // caseArray: string[]
|
|
166
|
+
type R = DropLast<[]> // caseEmptyTuple: []
|
|
167
|
+
|
|
168
|
+
// customization
|
|
169
|
+
type R = DropLast<string[], { caseArray: 1 }> // 1
|
|
170
|
+
type R = DropLast<[], { caseEmptyTuple: 1 }> // 1
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## [DropMatch](./drop.ts)
|
|
174
|
+
|
|
175
|
+
`DropMatch<A extends Readonly<Array<unknown>>, Criteria>`
|
|
176
|
+
|
|
177
|
+
⚗️ *transform*
|
|
178
|
+
|
|
179
|
+
Drops entries matching `Criteria` in array or tuple `A`.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
type R = DropMatch<Array<string | undefined>, undefined> // string[]
|
|
183
|
+
type R = DropMatch<Array<string>, string> // never[]
|
|
184
|
+
type R = DropMatch<Array<1 | 2>, number> // never[]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## [TuplePlus](./tuple_plus.ts)
|
|
188
|
+
|
|
189
|
+
`TuplePlus` contains type utilities specific for *tuple*.
|
|
190
|
+
The input type are not checked and assumed to be *tuple*.
|
|
191
|
+
|
|
192
|
+
## [TuplePlus.CommonPropKeys](./tuple_plus.common_prop_keys.ts#l22)
|
|
193
|
+
|
|
194
|
+
`TuplePlus.CommonPropKeys<T extends Record[], Options = { caseNever }>`
|
|
195
|
+
|
|
196
|
+
⚗️ *transform*
|
|
197
|
+
🔢 *customizable*
|
|
198
|
+
|
|
199
|
+
Gets the common property keys of the elements in tuple `T`.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { type TuplePlus } from 'type-plus'
|
|
14
203
|
|
|
15
|
-
type R =
|
|
16
|
-
type R =
|
|
204
|
+
type R = TuplePlus.CommonPropKeys<[{ a: 1, c: 1 }, { b: 1, c: 2 }]> // 'c'
|
|
205
|
+
type R = TuplePlus.CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
|
|
206
|
+
type R = TuplePlus.CommonPropKeys<Array<{ a: 1, b: 1 } | { a: 1, c: 1 }>> // 'a'
|
|
207
|
+
type R = TuplePlus.CommonPropKeys<[{ a: 1 }, { b: 1 }]> // never
|
|
208
|
+
type R = TuplePlus.CommonPropKeys<never> // caseNever: never
|
|
209
|
+
|
|
210
|
+
// customization
|
|
211
|
+
type R = TuplePlus.CommonPropKeys<never, { caseNever: 1 }> // 1
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### [TuplePlus.Filter](./tuple_plus.filter.ts)
|
|
215
|
+
|
|
216
|
+
`TuplePlus.Filter<T, Criteria>`
|
|
217
|
+
|
|
218
|
+
⚗️ *transform*
|
|
219
|
+
|
|
220
|
+
Filter entries matching `Criteria` in tuple `T`.
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
import { TuplePlus } from 'type-plus'
|
|
224
|
+
|
|
225
|
+
type R = TuplePlus.Filter<[1, 2, '3'], number> // [1, 2]
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### [`TuplePlus.Find`](./tuple_plus.find.ts#l51)
|
|
229
|
+
|
|
230
|
+
`TuplePlus.Find<A, Criteria, Options { widen, caseArray, caseEmptyTuple, caseNever, caseNotMatch, caseWiden, caseUnionNotMatch }>`
|
|
231
|
+
|
|
232
|
+
🦴 *utilities*
|
|
233
|
+
🔢 *customizable*
|
|
234
|
+
|
|
235
|
+
Finds the type in tuple `A` that matches `Criteria`.
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import type { TuplePlus } from 'type-plus'
|
|
239
|
+
|
|
240
|
+
type R = TuplePlus.Find<[true, 1, 'x', 3], string> // 'x'
|
|
241
|
+
type R = TuplePlus.Find<[true, 1, 'x', 3], number> // 1
|
|
242
|
+
type R = TuplePlus.Find<[string, number, 1], 1> // widen: 1 | undefined
|
|
243
|
+
type R = TuplePlus.Find<[true, number | string], string> // unionNotMatch: string
|
|
244
|
+
|
|
245
|
+
type R = TuplePlus.Find<[true, 1, 'x'], 2> // never
|
|
246
|
+
|
|
247
|
+
// customization
|
|
248
|
+
type R = TuplePlus.Find<[number], 1, { widen: false }> // never
|
|
249
|
+
type R = TuplePlus.Find<[number], 1, { caseWiden: never }> // never
|
|
250
|
+
type R = TuplePlus.Find<string[], 1, { caseArray: 2 }> // 2
|
|
251
|
+
type R = TuplePlus.Find<[], 1, { caseEmptyTuple: 2 }> // 2
|
|
252
|
+
type R = TuplePlus.Find<never, 1, { caseNever: 2 }> // 2
|
|
253
|
+
type R = TuplePlus.Find<[string], number, { caseNotMatch: 2 }> // 2
|
|
254
|
+
type R = TuplePlus.Find<[string | number], number, { caseUnionNotMatch: undefined }> // number | undefined
|
|
17
255
|
```
|
|
18
256
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
257
|
+
### [TuplePlus.PadStart](./tuple_plus.pad_start.ts)
|
|
258
|
+
|
|
259
|
+
`TuplePlus.PadStart<T, MaxLength, PadWith>`
|
|
260
|
+
|
|
261
|
+
⚗️ *transform*
|
|
262
|
+
|
|
263
|
+
Pad `T` with `PadWith` at the start of the tuple.
|
|
264
|
+
|
|
265
|
+
If the `MaxLength` is less than the length of the tuple,
|
|
266
|
+
the `Tuple` will be returned unchanged.
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
PadStart<[1, 2, 3], 5, 0> // [0, 0, 1, 2, 3]
|
|
270
|
+
|
|
271
|
+
// Ignore if MaxLength is less than the length of the tuple
|
|
272
|
+
PadStart<[1, 2, 3], 2> // [1, 2, 3]
|
|
273
|
+
|
|
274
|
+
// Default to unknown
|
|
275
|
+
PadStart<[1, 2, 3], 5> // [unknown, unknown, 1, 2, 3]
|
|
276
|
+
```
|
|
23
277
|
|
|
24
278
|
## References
|
|
25
279
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { NeverType } from '../never/never_type.js'
|
|
2
|
+
import type { KeyTypes } from '../object/KeyTypes.js'
|
|
3
|
+
import type { Tail } from './tail.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ⚗️ *transform*
|
|
7
|
+
* 🔢 *customization*
|
|
8
|
+
*
|
|
9
|
+
* Gets the common property keys of the elements in tuple `T`.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { type TuplePlus } from 'type-plus'
|
|
14
|
+
*
|
|
15
|
+
* type R = TuplePlus.CommonPropKeys<[{ a: number }, { b: number }]> // never
|
|
16
|
+
* type R = TuplePlus.CommonPropKeys<[{ a: number, c: 1 }, { b: number, c: 2 }]> // 'c'
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @typeParam Options['caseNever'] Return type when `T` is `never`.
|
|
20
|
+
* Default to `never`.
|
|
21
|
+
*/
|
|
22
|
+
export type CommonPropKeys<
|
|
23
|
+
T extends Record<KeyTypes, unknown>[],
|
|
24
|
+
Options extends CommonPropKeys.Options = CommonPropKeys.DefaultOptions
|
|
25
|
+
> = NeverType<
|
|
26
|
+
T,
|
|
27
|
+
Options['caseNever'],
|
|
28
|
+
(T['length'] extends 0
|
|
29
|
+
? never
|
|
30
|
+
: (
|
|
31
|
+
T['length'] extends 1
|
|
32
|
+
? keyof T[0]
|
|
33
|
+
: (
|
|
34
|
+
T['length'] extends 2
|
|
35
|
+
? keyof T[0] & keyof T[1]
|
|
36
|
+
: keyof T[0] & keyof T[1] & CommonPropKeys<Tail<Tail<T>>>
|
|
37
|
+
)
|
|
38
|
+
))
|
|
39
|
+
>
|
|
40
|
+
|
|
41
|
+
export namespace CommonPropKeys {
|
|
42
|
+
export interface Options extends NeverType.Options {
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface DefaultOptions extends NeverType.DefaultOptions {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IsEqual } from '../equal/equal.js'
|
|
2
|
+
|
|
3
|
+
export type DropMatch<A extends Readonly<Array<unknown>>, Criteria> = A['length'] extends 0
|
|
4
|
+
? // empty tuple
|
|
5
|
+
A
|
|
6
|
+
: A extends readonly [infer Head, ...infer Tail]
|
|
7
|
+
? Tail['length'] extends 0
|
|
8
|
+
? // single element tuple
|
|
9
|
+
undefined extends Criteria
|
|
10
|
+
? DropMatch.ExcludeUnionOfEmptyTuple<Head extends Criteria ? [] : [Head]>
|
|
11
|
+
: DropMatch.ExcludeUnionOfEmptyTuple<Head extends Criteria ? [] : [Head]>
|
|
12
|
+
: // multiple elements
|
|
13
|
+
Exclude<Head, Criteria> extends never
|
|
14
|
+
? DropMatch<Tail, Criteria>
|
|
15
|
+
: [Exclude<Head, Criteria>, ...DropMatch<Tail, Criteria>]
|
|
16
|
+
: never[]
|
|
17
|
+
|
|
18
|
+
export namespace DropMatch {
|
|
19
|
+
export type ExcludeUnionOfEmptyTuple<A> = IsEqual<A, []> extends true ? A : Exclude<A, []>
|
|
20
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⚗️ *transform*
|
|
3
|
+
*
|
|
4
|
+
* Filter entries matching `Criteria` in tuple `T`.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* type R = Filter<[1, 2, '3'], number> // [1, 2]
|
|
9
|
+
* type R = Filter<[1, 2, '3'], true> // []
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export type Filter<T extends unknown[], Criteria> = T['length'] extends 0
|
|
13
|
+
? []
|
|
14
|
+
: (
|
|
15
|
+
T extends [infer Head, ...infer Tail]
|
|
16
|
+
? (
|
|
17
|
+
Tail['length'] extends 0
|
|
18
|
+
? (
|
|
19
|
+
Head extends Criteria
|
|
20
|
+
? [Head]
|
|
21
|
+
: [])
|
|
22
|
+
: (
|
|
23
|
+
Head extends Criteria
|
|
24
|
+
? [Head, ...Filter<Tail, Criteria>]
|
|
25
|
+
: Filter<Tail, Criteria>
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
: never
|
|
29
|
+
)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { ElementMatch } from '../array/array_plus.element_match.js'
|
|
2
|
+
import type { NeverType } from '../never/never_type.js'
|
|
3
|
+
import type { MergeOptions } from '../utils/options.js'
|
|
4
|
+
import type { TupleType } from './tuple_type.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 🦴 *utilities*
|
|
8
|
+
* 🔢 *customizable*
|
|
9
|
+
*
|
|
10
|
+
* Find the first type in tuple `A` that matches `Criteria`.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* type R = TuplePlus.Find<[true, 1, 'x', 3], string> // 'x'
|
|
15
|
+
* type R = TuplePlus.Find<[true, 1, 'x', 3], number> // 1
|
|
16
|
+
* type R = TuplePlus.Find<[string, number, 1], 1> // widen: 1 | undefined
|
|
17
|
+
* type R = TuplePlus.Find<[true, number | string], string> // unionMiss: string | undefined
|
|
18
|
+
*
|
|
19
|
+
* type R = TuplePlus.Find<[true, 1, 'x'], 2> // never
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @typeParam Options['widen'] performs widen match.
|
|
23
|
+
* Default to `true`.
|
|
24
|
+
* With widen match, a narrowed type will match its widen type.
|
|
25
|
+
* e.g. matching `1` against `number` yields `1 | undefined`
|
|
26
|
+
*
|
|
27
|
+
* The widen behavior can be customized by `Options['caseWiden']`
|
|
28
|
+
*
|
|
29
|
+
* @typeParam Options['caseArray'] return type when `A` is an array. Default to `not supported` message.
|
|
30
|
+
*
|
|
31
|
+
* @typeParam Options['caseEmptyTuple'] return type when `A` is an empty tuple.
|
|
32
|
+
* Default to `never`.
|
|
33
|
+
*
|
|
34
|
+
* @typeParam Options['caseNever'] return type when `A` is `never`. Default to `never`.
|
|
35
|
+
*
|
|
36
|
+
* @typeParam Options['caseNotMatch'] Return value when `T` does not match `Criteria`.
|
|
37
|
+
* Default to `never`.
|
|
38
|
+
*
|
|
39
|
+
* @typeParam Options['caseWiden'] return type when `T` in `A` is a widen type of `Criteria`.
|
|
40
|
+
* Default to `Criteria | undefined`.
|
|
41
|
+
* Set it to `never` for a more type-centric behavior
|
|
42
|
+
*
|
|
43
|
+
* @typeParam Options['caseUnionNotMatch'] Return value when a branch of the union `T` does not match `Criteria`.
|
|
44
|
+
* Default to `never`.
|
|
45
|
+
*
|
|
46
|
+
* If you want the type to behave more like JavaScript,
|
|
47
|
+
* you can override it to return `undefined`.
|
|
48
|
+
*
|
|
49
|
+
* Since it is a union, the result will be joined to the matched branch as union.
|
|
50
|
+
*/
|
|
51
|
+
export type Find<
|
|
52
|
+
A extends unknown[],
|
|
53
|
+
Criteria,
|
|
54
|
+
Options extends Find.Options = Find.DefaultOptions<Criteria>
|
|
55
|
+
> = MergeOptions<Options, Find.DefaultOptions<Criteria>> extends infer O extends Find.Options
|
|
56
|
+
? TupleType<
|
|
57
|
+
A,
|
|
58
|
+
A['length'] extends 0
|
|
59
|
+
? O['caseEmptyTuple']
|
|
60
|
+
: Find.Device<A, Criteria, O>,
|
|
61
|
+
O['caseArray'],
|
|
62
|
+
O
|
|
63
|
+
>
|
|
64
|
+
: never
|
|
65
|
+
export namespace Find {
|
|
66
|
+
export type Device<
|
|
67
|
+
A extends unknown[],
|
|
68
|
+
Criteria,
|
|
69
|
+
Options extends Find.Options
|
|
70
|
+
> = A['length'] extends 0
|
|
71
|
+
? Options['caseNotMatch']
|
|
72
|
+
: (A extends [infer Head, ...infer Tail]
|
|
73
|
+
? ElementMatch<
|
|
74
|
+
Head,
|
|
75
|
+
Criteria,
|
|
76
|
+
MergeOptions<{ caseNotMatch: Device<Tail, Criteria, Options> }, Options>
|
|
77
|
+
>
|
|
78
|
+
: never)
|
|
79
|
+
export interface Options extends ElementMatch.Options, NeverType.Options {
|
|
80
|
+
caseArray?: unknown,
|
|
81
|
+
caseEmptyTuple?: unknown,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface DefaultOptions<Criteria> extends ElementMatch.DefaultOptions<Criteria>, NeverType.DefaultOptions {
|
|
85
|
+
caseArray: 'does not support array. Please use `FindFirst` or `ArrayPlus.Find` instead.',
|
|
86
|
+
caseEmptyTuple: never,
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -1,42 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Pad `T` with `PadWith` at the start of the tuple.
|
|
3
3
|
*
|
|
4
4
|
* If the `MaxLength` is less than the length of the tuple,
|
|
5
5
|
* the `Tuple` will be returned unchanged.
|
|
6
6
|
*
|
|
7
|
+
* ⚗️ *transform*
|
|
8
|
+
*
|
|
7
9
|
* @example
|
|
8
10
|
* ```ts
|
|
9
11
|
* PadStart<[1, 2, 3], 5, 0> // [0, 0, 1, 2, 3]
|
|
10
12
|
*
|
|
11
13
|
* // Ignore if MaxLength is less than the length of the tuple
|
|
12
|
-
* PadStart<[1, 2, 3],
|
|
14
|
+
* PadStart<[1, 2, 3], 2> // [1, 2, 3]
|
|
13
15
|
*
|
|
14
16
|
* // Default to unknown
|
|
15
17
|
* PadStart<[1, 2, 3], 5> // [unknown, unknown, 1, 2, 3]
|
|
16
18
|
* ```
|
|
17
19
|
*/
|
|
18
|
-
export type PadStart<Tuple extends unknown[], MaxLength extends number, PadWith = unknown> =
|
|
20
|
+
export type PadStart<Tuple extends unknown[], MaxLength extends number, PadWith = unknown> = PadStart.Device<
|
|
19
21
|
Tuple,
|
|
20
22
|
MaxLength,
|
|
21
23
|
PadWith,
|
|
22
24
|
[]
|
|
23
25
|
>
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
?
|
|
36
|
-
:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
export namespace PadStart {
|
|
28
|
+
export type Device<
|
|
29
|
+
Source extends unknown[],
|
|
30
|
+
MaxLength extends number,
|
|
31
|
+
PadWith,
|
|
32
|
+
Result extends unknown[]
|
|
33
|
+
> =
|
|
34
|
+
Result['length'] extends MaxLength
|
|
35
|
+
? (
|
|
36
|
+
Source extends []
|
|
37
|
+
? Result
|
|
38
|
+
: (
|
|
39
|
+
Source extends [...infer Head, infer Tail]
|
|
40
|
+
? (
|
|
41
|
+
[Tail, ...Result] extends infer R extends unknown[]
|
|
42
|
+
? Device<Head, R['length'], PadWith, R>
|
|
43
|
+
: never
|
|
44
|
+
)
|
|
45
|
+
: never
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
: (
|
|
49
|
+
Source extends []
|
|
50
|
+
? Device<Source, MaxLength, PadWith, [PadWith, ...Result]>
|
|
51
|
+
: (
|
|
52
|
+
Source extends [...infer Head, infer Tail]
|
|
53
|
+
? Device<Head, MaxLength, PadWith, [Tail, ...Result]>
|
|
54
|
+
: Source
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
}
|
package/ts/tuple/tuple_plus.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type { CommonPropKeys } from './tuple_plus.common_prop_keys.js'
|
|
2
|
+
export type { DropMatch } from './tuple_plus.drop_match.js'
|
|
3
|
+
export type { Filter } from './tuple_plus.filter.js'
|
|
4
|
+
export type { Find } from './tuple_plus.find.js'
|
|
5
|
+
export type { PadStart } from './tuple_plus.pad_start.js'
|