@rzl-zone/utils-js 3.13.1-beta.0 → 3.14.0-beta.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 +7 -6
- package/dist/.references/index.d.cts +2 -1
- package/dist/.references/index.d.ts +2 -1
- package/dist/AbortError-DK6kpzbu.cjs +26 -0
- package/dist/AbortError-DK6kpzbu.cjs.map +1 -0
- package/dist/AbortError-DVT8lAKn.js +20 -0
- package/dist/AbortError-DVT8lAKn.js.map +1 -0
- package/dist/{assertIsArray-DrLORH0Y.js → assertIsArray-CG7L7vlt.js} +3 -3
- package/dist/assertIsArray-CG7L7vlt.js.map +1 -0
- package/dist/{assertIsArray-CqIFmlgj.cjs → assertIsArray-CtCRD-_G.cjs} +5 -5
- package/dist/assertIsArray-CtCRD-_G.cjs.map +1 -0
- package/dist/assertIsPlainObject-DPZLj-Ho.cjs +26 -0
- package/dist/assertIsPlainObject-DPZLj-Ho.cjs.map +1 -0
- package/dist/assertIsPlainObject-j9bDqNLo.js +20 -0
- package/dist/assertIsPlainObject-j9bDqNLo.js.map +1 -0
- package/dist/{assertIsString-1iLqxrN0.js → assertIsString-CHIwE12y.js} +4 -4
- package/dist/assertIsString-CHIwE12y.js.map +1 -0
- package/dist/{assertIsString-DGDLC-XD.cjs → assertIsString-CjE9kbQ_.cjs} +6 -6
- package/dist/assertIsString-CjE9kbQ_.cjs.map +1 -0
- package/dist/assertions/index.cjs +14 -12
- package/dist/assertions/index.cjs.map +1 -1
- package/dist/assertions/index.d.cts +2 -2
- package/dist/assertions/index.d.ts +2 -2
- package/dist/assertions/index.js +10 -8
- package/dist/assertions/index.js.map +1 -1
- package/dist/conversions/index.cjs +6 -6
- package/dist/conversions/index.d.cts +2 -2
- package/dist/conversions/index.d.ts +2 -2
- package/dist/conversions/index.js +6 -6
- package/dist/conversions-BFz6MKaV.cjs +449 -0
- package/dist/conversions-BFz6MKaV.cjs.map +1 -0
- package/dist/{conversions-CA_3PTAH.js → conversions-Ben5p5Ts.js} +43 -40
- package/dist/conversions-Ben5p5Ts.js.map +1 -0
- package/dist/errors/index.cjs +13 -0
- package/dist/errors/index.d.cts +180 -0
- package/dist/errors/index.d.ts +180 -0
- package/dist/errors/index.js +11 -0
- package/dist/events/index.cjs +10 -9
- package/dist/events/index.cjs.map +1 -1
- package/dist/events/index.d.cts +185 -100
- package/dist/events/index.d.ts +185 -100
- package/dist/events/index.js +9 -8
- package/dist/events/index.js.map +1 -1
- package/dist/formatter-ekJQF_bA-BepnCBkQ.cjs +67 -0
- package/dist/formatter-ekJQF_bA-BepnCBkQ.cjs.map +1 -0
- package/dist/formatter-ekJQF_bA-xLD9mGk4.js +55 -0
- package/dist/formatter-ekJQF_bA-xLD9mGk4.js.map +1 -0
- package/dist/formatters/index.cjs +2 -2
- package/dist/formatters/index.d.cts +2 -2
- package/dist/formatters/index.d.ts +2 -2
- package/dist/formatters/index.js +2 -2
- package/dist/{formatters-Bm3a_akj.js → formatters-BAbGsnYA.js} +78 -71
- package/dist/formatters-BAbGsnYA.js.map +1 -0
- package/dist/formatters-zd0Gs4Cs.cjs +436 -0
- package/dist/formatters-zd0Gs4Cs.cjs.map +1 -0
- package/dist/generators/index.cjs +37 -31
- package/dist/generators/index.cjs.map +1 -1
- package/dist/generators/index.d.cts +2 -2
- package/dist/generators/index.d.ts +2 -2
- package/dist/generators/index.js +29 -23
- package/dist/generators/index.js.map +1 -1
- package/dist/hasOwnProp-CVIhlD1i.js +47 -0
- package/dist/hasOwnProp-CVIhlD1i.js.map +1 -0
- package/dist/hasOwnProp-D9Tpgokd.cjs +53 -0
- package/dist/hasOwnProp-D9Tpgokd.cjs.map +1 -0
- package/dist/{index-CakviK5E.d.cts → index-9JsU_wMu.d.ts} +1375 -937
- package/dist/{index-BqkYm8qT.d.ts → index-BP3sUrAx.d.ts} +242 -133
- package/dist/{index-CJx0EFQ4.d.cts → index-BVovC-yK.d.cts} +229 -200
- package/dist/index-C1X6ha9s.d.cts +1041 -0
- package/dist/index-CcPQZ41G.d.cts +1103 -0
- package/dist/index-CjpbuJF4.d.ts +2424 -0
- package/dist/index-CssrQyHh.d.cts +2424 -0
- package/dist/index-DZHiYYR7.d.cts +2179 -0
- package/dist/index-DZHiYYR7.d.ts +2179 -0
- package/dist/index-DlyDmXUo.d.ts +1103 -0
- package/dist/index-Dm4a___O.d.ts +1041 -0
- package/dist/{index-D5nTp1kV.d.ts → index-Dwduk7ez.d.cts} +1375 -937
- package/dist/{index-uaHl0X-r.d.cts → index-I5V6RbZM.d.cts} +1592 -790
- package/dist/{index-Bm5odgLW.d.ts → index-hOqBIL7F.d.ts} +1592 -790
- package/dist/{index-hOCUw-B9.d.ts → index-jyuOZMX7.d.ts} +229 -200
- package/dist/{index-BqkYm8qT.d.cts → index-lI0b7iUz.d.cts} +242 -133
- package/dist/{isBigInt-f6yY2fAV.js → isBigInt-Cez32M69.js} +2 -2
- package/dist/isBigInt-Cez32M69.js.map +1 -0
- package/dist/{isBigInt-CqZNWVtI.cjs → isBigInt-YgpNKTbA.cjs} +2 -2
- package/dist/isBigInt-YgpNKTbA.cjs.map +1 -0
- package/dist/{isEmptyString-Ga77_3Q1.js → isEmptyString-C9QLWjx2.js} +4 -4
- package/dist/isEmptyString-C9QLWjx2.js.map +1 -0
- package/dist/{isEmptyString-DNMPmS-H.cjs → isEmptyString-O4TFe1Ao.cjs} +5 -5
- package/dist/isEmptyString-O4TFe1Ao.cjs.map +1 -0
- package/dist/isEmptyValue-CFExALXZ.cjs +54 -0
- package/dist/isEmptyValue-CFExALXZ.cjs.map +1 -0
- package/dist/isEmptyValue-kCjnLjbN.js +36 -0
- package/dist/isEmptyValue-kCjnLjbN.js.map +1 -0
- package/dist/{isFinite-Crw95XV8.cjs → isFinite-B_hHbDpa.cjs} +6 -6
- package/dist/isFinite-B_hHbDpa.cjs.map +1 -0
- package/dist/{isFinite-BJO7Dt6B.js → isFinite-ZvNhyHlF.js} +5 -5
- package/dist/isFinite-ZvNhyHlF.js.map +1 -0
- package/dist/{isInteger-B75voxys.js → isInteger-aZgzTTZG.js} +4 -4
- package/dist/isInteger-aZgzTTZG.js.map +1 -0
- package/dist/{isInteger-CSMNm--9.cjs → isInteger-dnc6W63Z.cjs} +4 -4
- package/dist/isInteger-dnc6W63Z.cjs.map +1 -0
- package/dist/isNumber-BCWD4dW0.js +20 -0
- package/dist/isNumber-BCWD4dW0.js.map +1 -0
- package/dist/isNumber-BkzwAe50.cjs +26 -0
- package/dist/isNumber-BkzwAe50.cjs.map +1 -0
- package/dist/isPlainObject-CAe_ElKO.d.cts +331 -0
- package/dist/isPlainObject-CJvRG4Je.d.ts +331 -0
- package/dist/{isServer-BHOSvBhV.js → isServer-CQzrX5e0.js} +2 -2
- package/dist/isServer-CQzrX5e0.js.map +1 -0
- package/dist/{isServer-HA13Dzo2.cjs → isServer-DhFaedeT.cjs} +2 -2
- package/dist/isServer-DhFaedeT.cjs.map +1 -0
- package/dist/{isEqual-D8W3Wizi.cjs → isTypedArray-DjADSu8q.cjs} +45 -13
- package/dist/isTypedArray-DjADSu8q.cjs.map +1 -0
- package/dist/{isEqual-ekId-j5b.js → isTypedArray-DxsPKrLh.js} +29 -9
- package/dist/isTypedArray-DxsPKrLh.js.map +1 -0
- package/dist/{isValidDomain-BqyLVi7S.js → isValidDomain-CDtNOhMc.js} +13 -54
- package/dist/isValidDomain-CDtNOhMc.js.map +1 -0
- package/dist/{isValidDomain-ByrOfQsh.cjs → isValidDomain-D_x7uNIu.cjs} +16 -69
- package/dist/isValidDomain-D_x7uNIu.cjs.map +1 -0
- package/dist/{assertIsBoolean-DDhQ2D-k.js → logger-CLWnKRKE.js} +657 -587
- package/dist/logger-CLWnKRKE.js.map +1 -0
- package/dist/{assertIsBoolean-CEx4KbHg.cjs → logger-CUacYy3D.cjs} +658 -612
- package/dist/logger-CUacYy3D.cjs.map +1 -0
- package/dist/{noop-CkwxErJ2.cjs → noop-CjEbNsJL.cjs} +2 -2
- package/dist/noop-CjEbNsJL.cjs.map +1 -0
- package/dist/{noop-D_Ots__Z.js → noop-qxrcogt5.js} +2 -2
- package/dist/noop-qxrcogt5.js.map +1 -0
- package/dist/{normalizeSpaces-88yaixiu.cjs → normalizeSpaces-D0_Z4qnO.cjs} +6 -9
- package/dist/normalizeSpaces-D0_Z4qnO.cjs.map +1 -0
- package/dist/{normalizeSpaces-Cat8CHtt.js → normalizeSpaces-DAsxzBEQ.js} +4 -7
- package/dist/normalizeSpaces-DAsxzBEQ.js.map +1 -0
- package/dist/operations/index.cjs +152 -22
- package/dist/operations/index.cjs.map +1 -1
- package/dist/operations/index.d.cts +257 -35
- package/dist/operations/index.d.ts +257 -35
- package/dist/operations/index.js +142 -13
- package/dist/operations/index.js.map +1 -1
- package/dist/parsers/index.cjs +2 -2
- package/dist/parsers/index.d.cts +238 -180
- package/dist/parsers/index.d.ts +238 -180
- package/dist/parsers/index.js +2 -2
- package/dist/{parsers-BLHzVoh-.js → parsers-BBAE_xVM.js} +9 -8
- package/dist/parsers-BBAE_xVM.js.map +1 -0
- package/dist/{parsers-xAQmKCgS.cjs → parsers-i8WEeMJl.cjs} +10 -9
- package/dist/parsers-i8WEeMJl.cjs.map +1 -0
- package/dist/{parsing-BYo6U0EG.js → parsing-D9tbKQ0v.js} +3 -3
- package/dist/parsing-D9tbKQ0v.js.map +1 -0
- package/dist/{parsing-CuezVd0e.cjs → parsing-DGjB8cwr.cjs} +4 -4
- package/dist/parsing-DGjB8cwr.cjs.map +1 -0
- package/dist/predicates/index.cjs +43 -43
- package/dist/predicates/index.d.cts +3 -3
- package/dist/predicates/index.d.ts +3 -3
- package/dist/predicates/index.js +14 -14
- package/dist/{predicates-BMTIIYx8.js → predicates-C0dova7l.js} +45 -40
- package/dist/predicates-C0dova7l.js.map +1 -0
- package/dist/{predicates-ZmZpelMh.cjs → predicates-Dd7To7B4.cjs} +89 -84
- package/dist/predicates-Dd7To7B4.cjs.map +1 -0
- package/dist/promises/index.cjs +27 -26
- package/dist/promises/index.cjs.map +1 -1
- package/dist/promises/index.d.cts +227 -75
- package/dist/promises/index.d.ts +227 -75
- package/dist/promises/index.js +27 -26
- package/dist/promises/index.js.map +1 -1
- package/dist/{punyCode-WZ6-GaTM.cjs → punyCode-DHTLhGdD.cjs} +12 -12
- package/dist/punyCode-DHTLhGdD.cjs.map +1 -0
- package/dist/{punyCode-COTqgXMJ.js → punyCode-Deb1Mrkc.js} +12 -12
- package/dist/punyCode-Deb1Mrkc.js.map +1 -0
- package/dist/{removeSpaces-CQJvw1yU.js → removeSpaces-BPnsdRN0.js} +4 -4
- package/dist/removeSpaces-BPnsdRN0.js.map +1 -0
- package/dist/{removeSpaces-BeGkktUl.cjs → removeSpaces-CN3pxBz_.cjs} +7 -7
- package/dist/removeSpaces-CN3pxBz_.cjs.map +1 -0
- package/dist/rzl-utils.global.js +13 -13
- package/dist/safeJsonParse-D1FLVTEM.cjs +209 -0
- package/dist/safeJsonParse-D1FLVTEM.cjs.map +1 -0
- package/dist/{safeJsonParse-D8H3wCv7.js → safeJsonParse-DEVKNDSn.js} +29 -28
- package/dist/safeJsonParse-DEVKNDSn.js.map +1 -0
- package/dist/safeStableStringify-C5HHKUdn.cjs +125 -0
- package/dist/safeStableStringify-C5HHKUdn.cjs.map +1 -0
- package/dist/{safeStableStringify-BLwA1VC-.js → safeStableStringify-DfwxmiWn.js} +20 -13
- package/dist/safeStableStringify-DfwxmiWn.js.map +1 -0
- package/dist/strings/index.cjs +26 -30
- package/dist/strings/index.cjs.map +1 -1
- package/dist/strings/index.d.cts +2 -2
- package/dist/strings/index.d.ts +2 -2
- package/dist/strings/index.js +13 -17
- package/dist/strings/index.js.map +1 -1
- package/dist/tailwind/index.cjs +3 -3
- package/dist/tailwind/index.d.cts +3 -3
- package/dist/tailwind/index.d.ts +3 -3
- package/dist/tailwind/index.js +3 -3
- package/dist/{tailwind-CjxdO7aL.cjs → tailwind-BG7B0cDs.cjs} +59 -53
- package/dist/tailwind-BG7B0cDs.cjs.map +1 -0
- package/dist/{tailwind-RSE3obLb.js → tailwind-tJNnFPsF.js} +38 -32
- package/dist/tailwind-tJNnFPsF.js.map +1 -0
- package/dist/{toStringArrayUnRecursive-NreW1dyV.js → toStringArrayUnRecursive-D0WbLIRz.js} +9 -9
- package/dist/toStringArrayUnRecursive-D0WbLIRz.js.map +1 -0
- package/dist/toStringArrayUnRecursive-QLoaNX_-.cjs +51 -0
- package/dist/toStringArrayUnRecursive-QLoaNX_-.cjs.map +1 -0
- package/dist/urls/index.cjs +3 -3
- package/dist/urls/index.d.cts +635 -443
- package/dist/urls/index.d.ts +635 -443
- package/dist/urls/index.js +3 -3
- package/dist/{urls-CLVfEB7O.js → urls-EoWslGgg.js} +50 -41
- package/dist/urls-EoWslGgg.js.map +1 -0
- package/dist/urls-NCzPepe2.cjs +308 -0
- package/dist/urls-NCzPepe2.cjs.map +1 -0
- package/package.json +6 -6
- package/dist/assertIsArray-CqIFmlgj.cjs.map +0 -1
- package/dist/assertIsArray-DrLORH0Y.js.map +0 -1
- package/dist/assertIsBoolean-CEx4KbHg.cjs.map +0 -1
- package/dist/assertIsBoolean-DDhQ2D-k.js.map +0 -1
- package/dist/assertIsString-1iLqxrN0.js.map +0 -1
- package/dist/assertIsString-DGDLC-XD.cjs.map +0 -1
- package/dist/conversions-Bxa01uIl.cjs +0 -446
- package/dist/conversions-Bxa01uIl.cjs.map +0 -1
- package/dist/conversions-CA_3PTAH.js.map +0 -1
- package/dist/formatters-Bm3a_akj.js.map +0 -1
- package/dist/formatters-Bt6QuhxK.cjs +0 -429
- package/dist/formatters-Bt6QuhxK.cjs.map +0 -1
- package/dist/index--h04HuBE.d.cts +0 -765
- package/dist/index--h04HuBE.d.ts +0 -765
- package/dist/index-Ap8U-8Qx.d.cts +0 -947
- package/dist/index-BAeeggeh.d.cts +0 -1716
- package/dist/index-BAeeggeh.d.ts +0 -1716
- package/dist/index-CMglhpFG.d.ts +0 -947
- package/dist/isBigInt-CqZNWVtI.cjs.map +0 -1
- package/dist/isBigInt-f6yY2fAV.js.map +0 -1
- package/dist/isEmptyObject-BYNnSKzw.js +0 -25
- package/dist/isEmptyObject-BYNnSKzw.js.map +0 -1
- package/dist/isEmptyObject-C2lQyFZS.cjs +0 -37
- package/dist/isEmptyObject-C2lQyFZS.cjs.map +0 -1
- package/dist/isEmptyString-DNMPmS-H.cjs.map +0 -1
- package/dist/isEmptyString-Ga77_3Q1.js.map +0 -1
- package/dist/isEmptyValue-D7-6WWS9.js +0 -24
- package/dist/isEmptyValue-D7-6WWS9.js.map +0 -1
- package/dist/isEmptyValue-DZaDHEIw.cjs +0 -30
- package/dist/isEmptyValue-DZaDHEIw.cjs.map +0 -1
- package/dist/isEqual-D8W3Wizi.cjs.map +0 -1
- package/dist/isEqual-ekId-j5b.js.map +0 -1
- package/dist/isFinite-BJO7Dt6B.js.map +0 -1
- package/dist/isFinite-Crw95XV8.cjs.map +0 -1
- package/dist/isInteger-B75voxys.js.map +0 -1
- package/dist/isInteger-CSMNm--9.cjs.map +0 -1
- package/dist/isPlainObject-ByfuseCf.d.cts +0 -339
- package/dist/isPlainObject-ByfuseCf.d.ts +0 -339
- package/dist/isServer-BHOSvBhV.js.map +0 -1
- package/dist/isServer-HA13Dzo2.cjs.map +0 -1
- package/dist/isTypedArray-CWlHRz_O.cjs +0 -43
- package/dist/isTypedArray-CWlHRz_O.cjs.map +0 -1
- package/dist/isTypedArray-CmnQ7Yx9.js +0 -31
- package/dist/isTypedArray-CmnQ7Yx9.js.map +0 -1
- package/dist/isValidDomain-BqyLVi7S.js.map +0 -1
- package/dist/isValidDomain-ByrOfQsh.cjs.map +0 -1
- package/dist/noop-CkwxErJ2.cjs.map +0 -1
- package/dist/noop-D_Ots__Z.js.map +0 -1
- package/dist/normalizeSpaces-88yaixiu.cjs.map +0 -1
- package/dist/normalizeSpaces-Cat8CHtt.js.map +0 -1
- package/dist/parsers-BLHzVoh-.js.map +0 -1
- package/dist/parsers-xAQmKCgS.cjs.map +0 -1
- package/dist/parsing-BYo6U0EG.js.map +0 -1
- package/dist/parsing-CuezVd0e.cjs.map +0 -1
- package/dist/predicates-BMTIIYx8.js.map +0 -1
- package/dist/predicates-ZmZpelMh.cjs.map +0 -1
- package/dist/punyCode-COTqgXMJ.js.map +0 -1
- package/dist/punyCode-WZ6-GaTM.cjs.map +0 -1
- package/dist/removeSpaces-BeGkktUl.cjs.map +0 -1
- package/dist/removeSpaces-CQJvw1yU.js.map +0 -1
- package/dist/safeJsonParse-BznDD3fi.cjs +0 -208
- package/dist/safeJsonParse-BznDD3fi.cjs.map +0 -1
- package/dist/safeJsonParse-D8H3wCv7.js.map +0 -1
- package/dist/safeStableStringify-4b-E_UHM.cjs +0 -106
- package/dist/safeStableStringify-4b-E_UHM.cjs.map +0 -1
- package/dist/safeStableStringify-BLwA1VC-.js.map +0 -1
- package/dist/tailwind-CjxdO7aL.cjs.map +0 -1
- package/dist/tailwind-RSE3obLb.js.map +0 -1
- package/dist/toStringArrayUnRecursive-D-jHROts.cjs +0 -51
- package/dist/toStringArrayUnRecursive-D-jHROts.cjs.map +0 -1
- package/dist/toStringArrayUnRecursive-NreW1dyV.js.map +0 -1
- package/dist/urls-C6BvhrrV.cjs +0 -299
- package/dist/urls-C6BvhrrV.cjs.map +0 -1
- package/dist/urls-CLVfEB7O.js.map +0 -1
|
@@ -0,0 +1,2179 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ========================================================================
|
|
3
|
+
* @rzl-zone/utils-js
|
|
4
|
+
* ------------------------------------------------------------------------
|
|
5
|
+
* Version: `3.14.0-beta.0`
|
|
6
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky@gmail.com>`
|
|
7
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/utils-js`
|
|
8
|
+
* ========================================================================
|
|
9
|
+
*/
|
|
10
|
+
/*!
|
|
11
|
+
* ========================================================================
|
|
12
|
+
* @rzl-zone/ts-types-plus
|
|
13
|
+
* ------------------------------------------------------------------------
|
|
14
|
+
* Version: `0.1.8-beta.0`
|
|
15
|
+
* Author: `Rizalvin Dwiky <rizalvindwiky1998@gmail.com>`
|
|
16
|
+
* Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/ts-types-plus`
|
|
17
|
+
* ========================================================================
|
|
18
|
+
*/
|
|
19
|
+
/** -------------------------------------------------------
|
|
20
|
+
* * ***Utility Type: `If`.***
|
|
21
|
+
* -------------------------------------------------------
|
|
22
|
+
* - **Conditional:**
|
|
23
|
+
* - Returns the second argument if the first argument is `true`, otherwise
|
|
24
|
+
* returns the third argument.
|
|
25
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
26
|
+
* @template Condition - The boolean condition to check.
|
|
27
|
+
* @template IfTrue - The branch type if condition is `true`. (default: `true`).
|
|
28
|
+
* @template IfFalse - The branch type if condition is `false`. (default: `false`).
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* type A = If<true, "valid">;
|
|
32
|
+
* // ➔ "valid"
|
|
33
|
+
* type B = If<false, "valid", "invalid">;
|
|
34
|
+
* // ➔ "invalid"
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
type If<Condition, IfTrue = true, IfFalse = false> = Condition extends true ? IfTrue : IfFalse;
|
|
38
|
+
/** -------------------------------------------------------
|
|
39
|
+
* * ***Utility Type: `IsNever`.***
|
|
40
|
+
* -------------------------------------------------------
|
|
41
|
+
* ****Conditional**: returns `true` if `T` is `never`, otherwise `false`.**
|
|
42
|
+
* @template T - Type to check.
|
|
43
|
+
* @example
|
|
44
|
+
* ```ts
|
|
45
|
+
* type A = IsNever<never>; // ➔ true
|
|
46
|
+
* type B = IsNever<true>; // ➔ false
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
type IsNever<T> = [T] extends [never] ? true : false;
|
|
50
|
+
/** -------------------------------------------------------
|
|
51
|
+
* * ***Utility Type: `IfNever`.***
|
|
52
|
+
* -------------------------------------------------------
|
|
53
|
+
* **Conditional**: Selects one of two branches depending on whether `T` is `never`.**
|
|
54
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
55
|
+
* @template T - Type to check.
|
|
56
|
+
* @template IfTrue - The branch type if `T` is `never`, (default: `true`).
|
|
57
|
+
* @template IfFalse - The branch type if `T` is not `never`, (default: `false`).
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* type A = IfNever<never>;
|
|
61
|
+
* // ➔ true
|
|
62
|
+
* type B = IfNever<string>;
|
|
63
|
+
* // ➔ false
|
|
64
|
+
* type C = IfNever<never, 'valid', 'no'>;
|
|
65
|
+
* // ➔ 'valid'
|
|
66
|
+
* type D = IfNever<string, 'valid', 'no'>;
|
|
67
|
+
* // ➔ 'no'
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
/** -------------------------------------------------------
|
|
71
|
+
* * ***Utility Type: `EmptyArray`.***
|
|
72
|
+
* -------------------------------------------------------
|
|
73
|
+
* **A type-level utility that returns `T` if it is an ***empty array***,
|
|
74
|
+
* otherwise returns `never`.**
|
|
75
|
+
* @template T - The array type to check.
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* type A = EmptyArray<[]>;
|
|
79
|
+
* // ➔ []
|
|
80
|
+
* type B = EmptyArray<[1]>;
|
|
81
|
+
* // ➔ never
|
|
82
|
+
* type C = EmptyArray<string[]>;
|
|
83
|
+
* // ➔ string[]
|
|
84
|
+
* type D = EmptyArray<number[]>;
|
|
85
|
+
* // ➔ number[]
|
|
86
|
+
* type E = EmptyArray<readonly []>;
|
|
87
|
+
* // ➔ readonly []
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
type EmptyArray<T extends readonly unknown[]> = T extends readonly [unknown, ...unknown[]] ? never : T;
|
|
91
|
+
/** -------------------------------------------------------
|
|
92
|
+
* * ***Utility Type: `NonEmptyArray`.***
|
|
93
|
+
* -------------------------------------------------------
|
|
94
|
+
* **A type-level utility that returns `T` if it is a ***non-empty array***,
|
|
95
|
+
* otherwise returns `never`.**
|
|
96
|
+
* @template T - The array type to check.
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* type A = NonEmptyArray<[]>;
|
|
100
|
+
* // ➔ never
|
|
101
|
+
* type B = NonEmptyArray<[1]>;
|
|
102
|
+
* // ➔ [1]
|
|
103
|
+
* type C = NonEmptyArray<string[]>;
|
|
104
|
+
* // ➔ never
|
|
105
|
+
* type D = NonEmptyArray<number[]>;
|
|
106
|
+
* // ➔ never
|
|
107
|
+
* type E = NonEmptyArray<readonly []>;
|
|
108
|
+
* // ➔ never
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
/** -------------------------------------------------------
|
|
112
|
+
* * ***Utility Type: `IsNonEmptyArray`.***
|
|
113
|
+
* -------------------------------------------------------
|
|
114
|
+
* **A type-level utility that evaluates to `true` if `T` is a ***non-empty array.***
|
|
115
|
+
* (strictly a non-empty tuple), otherwise `false`.**
|
|
116
|
+
* @template T - The array type to check.
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* type A = IsNonEmptyArray<[]>;
|
|
120
|
+
* // ➔ false
|
|
121
|
+
* type B = IsNonEmptyArray<[1]>;
|
|
122
|
+
* // ➔ true
|
|
123
|
+
* type C = IsNonEmptyArray<string[]>;
|
|
124
|
+
* // ➔ false
|
|
125
|
+
* type D = IsNonEmptyArray<number[]>;
|
|
126
|
+
* // ➔ false
|
|
127
|
+
* type E = IsNonEmptyArray<readonly []>;
|
|
128
|
+
* // ➔ false
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
type IsNonEmptyArray<T extends readonly unknown[]> = If<IsNever<EmptyArray<T>>, true, false>;
|
|
132
|
+
/** -------------------------------------------------------
|
|
133
|
+
* * ***Utility Type: `IfEmptyArray`.***
|
|
134
|
+
* -------------------------------------------------------
|
|
135
|
+
* **Returns the second argument if `T` is an ***empty array*** (per this utility),
|
|
136
|
+
* otherwise returns the third argument.**
|
|
137
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
138
|
+
* @template T - The array type to check.
|
|
139
|
+
* @template IfTrue - Returned type if `T` is empty by this definition.
|
|
140
|
+
* @template IfFalse - Returned type if `T` is not empty by this definition.
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* type A = IfEmptyArray<[]>;
|
|
144
|
+
* // ➔ true
|
|
145
|
+
* type B = IfEmptyArray<[1]>;
|
|
146
|
+
* // ➔ false
|
|
147
|
+
* type C = IfEmptyArray<string[]>;
|
|
148
|
+
* // ➔ true
|
|
149
|
+
* type D = IfEmptyArray<readonly []>;
|
|
150
|
+
* // ➔ true
|
|
151
|
+
* type E = IfEmptyArray<[], "yes", "no">;
|
|
152
|
+
* // ➔ "yes"
|
|
153
|
+
* type F = IfEmptyArray<[1], "yes", "no">;
|
|
154
|
+
* // ➔ "no"
|
|
155
|
+
* type G = IfEmptyArray<string[], "yes", "no">;
|
|
156
|
+
* // ➔ "yes"
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
/** -------------------------------------------------------
|
|
160
|
+
* * ***Utility Type: `IfNonEmptyArray`.***
|
|
161
|
+
* -------------------------------------------------------
|
|
162
|
+
* **Returns the second argument if `T` is a ***non-empty array*** (strict tuple),
|
|
163
|
+
* otherwise returns the third argument.**
|
|
164
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
165
|
+
* @template T - The array type to check.
|
|
166
|
+
* @template IfTrue - Returned type if `T` is non-empty by this definition.
|
|
167
|
+
* @template IfFalse - Returned type if `T` is not non-empty by this definition.
|
|
168
|
+
* @example
|
|
169
|
+
* ```ts
|
|
170
|
+
* type A = IfNonEmptyArray<[]>;
|
|
171
|
+
* // ➔ false
|
|
172
|
+
* type B = IfNonEmptyArray<[1]>;
|
|
173
|
+
* // ➔ true
|
|
174
|
+
* type C = IfNonEmptyArray<string[]>;
|
|
175
|
+
* // ➔ false
|
|
176
|
+
* type D = IfNonEmptyArray<readonly []>;
|
|
177
|
+
* // ➔ false
|
|
178
|
+
* type E = IfNonEmptyArray<[1], "yes", "no">;
|
|
179
|
+
* // ➔ "yes"
|
|
180
|
+
* type F = IfNonEmptyArray<[], "yes", "no">;
|
|
181
|
+
* // ➔ "no"
|
|
182
|
+
* type G = IfNonEmptyArray<string[], "yes", "no">;
|
|
183
|
+
* // ➔ "no"
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
type IfNonEmptyArray<T extends readonly unknown[], IfTrue = true, IfFalse = false> = If<IsNonEmptyArray<T>, IfTrue, IfFalse>;
|
|
187
|
+
/** -------------------------------------------------------
|
|
188
|
+
* * ***Utility Type: `Not`.***
|
|
189
|
+
* -------------------------------------------------------
|
|
190
|
+
* **Accepts a boolean type `T` and returns its negation.**
|
|
191
|
+
* @template T - Boolean type to negate.
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* type A = Not<true>; // ➔ false
|
|
195
|
+
* type B = Not<false>; // ➔ true
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
type Not<T extends boolean> = T extends true ? false : true;
|
|
199
|
+
/** ---------------------------------------------------------------------------
|
|
200
|
+
* * ***Options for {@link Pop|`Pop`}.***
|
|
201
|
+
* ---------------------------------------------------------------------------
|
|
202
|
+
* **Configuration options for the {@link Pop | **`Pop`**} type utility.**
|
|
203
|
+
*/
|
|
204
|
+
/** -------------------------------------------------------
|
|
205
|
+
* * ***Utility Type: `Extends`.***
|
|
206
|
+
* -------------------------------------------------------
|
|
207
|
+
* **Returns a boolean indicating whether the first argument ***extends*** the second argument.**
|
|
208
|
+
* @template T - The type to check.
|
|
209
|
+
* @template Base - The type to compare against.
|
|
210
|
+
* @example
|
|
211
|
+
* ```ts
|
|
212
|
+
* type A = Extends<1, number>; // ➔ true
|
|
213
|
+
* type B = Extends<number, 1>; // ➔ false
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
type Extends<T, Base> = [T] extends [Base] ? true : false;
|
|
217
|
+
/** -------------------------------------------------------
|
|
218
|
+
* * ***Utility Type: `NotExtends`.***
|
|
219
|
+
* -------------------------------------------------------
|
|
220
|
+
* **Returns a boolean indicating whether the first argument does ***not extend*** the second argument.**
|
|
221
|
+
* @template T - The type to check.
|
|
222
|
+
* @template Base - The type to compare against.
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* type A = NotExtends<1, number>; // ➔ false
|
|
226
|
+
* type B = NotExtends<number, 1>; // ➔ true
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
type NotExtends<T, Base> = Not<Extends<T, Base>>;
|
|
230
|
+
/** -------------------------------------------------------
|
|
231
|
+
* * ***Utility Type: `IfExtends`.***
|
|
232
|
+
* -------------------------------------------------------
|
|
233
|
+
* - **Conditional:**
|
|
234
|
+
* - Returns the third argument if the first argument ***extends*** the second
|
|
235
|
+
* argument, otherwise returns the fourth argument.
|
|
236
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
237
|
+
* @template T - The type to check.
|
|
238
|
+
* @template Base - The type to compare against.
|
|
239
|
+
* @template IfTrue - The branch type if condition is met, (default: `true`).
|
|
240
|
+
* @template IfFalse - The branch type if condition is not met, (default: `false`).
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts
|
|
243
|
+
* type A = IfExtends<1, number, "valid">;
|
|
244
|
+
* // ➔ "valid"
|
|
245
|
+
* type B = IfExtends<1, string, "valid", "invalid">;
|
|
246
|
+
* // ➔ "invalid"
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
type IfExtends<T, Base, IfTrue = true, IfFalse = false> = If<Extends<T, Base>, IfTrue, IfFalse>;
|
|
250
|
+
/** -------------------------------------------------------
|
|
251
|
+
* * ***Utility Type: `IfNotExtends`.***
|
|
252
|
+
* -------------------------------------------------------
|
|
253
|
+
* - **Conditional:**
|
|
254
|
+
* - Returns the third argument if the first argument does ***not extend*** the
|
|
255
|
+
* second argument, otherwise returns the fourth argument.
|
|
256
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
257
|
+
* @template T - The type to check.
|
|
258
|
+
* @template Base - The type to compare against.
|
|
259
|
+
* @template IfTrue - The branch type if condition is met, (default: `true`).
|
|
260
|
+
* @template IfFalse - The branch type if condition is not met, (default: `false`).
|
|
261
|
+
* @example
|
|
262
|
+
* ```ts
|
|
263
|
+
* type A = IfNotExtends<1, string, "valid">;
|
|
264
|
+
* // ➔ "valid"
|
|
265
|
+
* type B = IfNotExtends<1, number, "valid", "invalid">;
|
|
266
|
+
* // ➔ "invalid"
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
type IfNotExtends<T, Base, IfTrue = true, IfFalse = false> = If<NotExtends<T, Base>, IfTrue, IfFalse>;
|
|
270
|
+
/** -------------------------------------------------------
|
|
271
|
+
* * ***Utility Type: `ExtendsArr`.***
|
|
272
|
+
* -------------------------------------------------------
|
|
273
|
+
* **Returns a boolean indicating whether every element of the first array argument ***extends*** the second argument.**
|
|
274
|
+
* @template T - The array to check.
|
|
275
|
+
* @template Base - The type to compare each element against.
|
|
276
|
+
* @example
|
|
277
|
+
* ```ts
|
|
278
|
+
* type A = ExtendsArr<[1, 2, 3], number>;
|
|
279
|
+
* // ➔ true
|
|
280
|
+
* type B = ExtendsArr<[1, "2", 3], number>;
|
|
281
|
+
* // ➔ false
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
/** -------------------------------------------------------
|
|
285
|
+
* * ***Utility Type: `And`.***
|
|
286
|
+
* -------------------------------------------------------
|
|
287
|
+
* **Performs a **logical AND** operation between two boolean types.**
|
|
288
|
+
* - **Behavior:**
|
|
289
|
+
* - Returns `true` if **both** conditions extend `true`.
|
|
290
|
+
* - Returns `false` for otherwise.
|
|
291
|
+
* @template Condition1 - The first condition.
|
|
292
|
+
* @template Condition2 - The second condition.
|
|
293
|
+
* @example
|
|
294
|
+
* ```ts
|
|
295
|
+
* type Case1 = And<true, true>;
|
|
296
|
+
* // ➔ true
|
|
297
|
+
* type Case2 = And<false, true>;
|
|
298
|
+
* // ➔ false
|
|
299
|
+
* type Case3 = And<true, false>;
|
|
300
|
+
* // ➔ false
|
|
301
|
+
* type Case4 = And<false, false>;
|
|
302
|
+
* // ➔ false
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
type And<Condition1, Condition2> = IfExtends<Condition1, true, Extends<Condition2, true>>;
|
|
306
|
+
/** -------------------------------------------------------
|
|
307
|
+
* * ***Utility Type: `AndArr`.***
|
|
308
|
+
* -------------------------------------------------------
|
|
309
|
+
* **Performs a **logical AND** operation across all elements in an array of
|
|
310
|
+
* boolean types.**
|
|
311
|
+
* - **Behavior:**
|
|
312
|
+
* - Returns `true` if **all elements** extend `true`.
|
|
313
|
+
* - Returns `false` if **any element** is not `true`.
|
|
314
|
+
* @template Conditions - A readonly array of boolean conditions.
|
|
315
|
+
* @example
|
|
316
|
+
* ```ts
|
|
317
|
+
* type Case1 = AndArr<[true, true, true]>;
|
|
318
|
+
* // ➔ true
|
|
319
|
+
* type Case2 = AndArr<[true, true, false]>;
|
|
320
|
+
* // ➔ false
|
|
321
|
+
* type Case3 = AndArr<[false, false, false]>;
|
|
322
|
+
* // ➔ false
|
|
323
|
+
* type Case4 = AndArr<[]>;
|
|
324
|
+
* // ➔ false
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
type AndArr<Conditions extends readonly unknown[]> = Extends<[], Conditions> extends true ? false : Extends<Conditions[number], true>;
|
|
328
|
+
/** -------------------------------------------------------
|
|
329
|
+
* * ***Utility Type: `IsStringLiteral`.***
|
|
330
|
+
* -------------------------------------------------------
|
|
331
|
+
* **Returns a boolean whether the passed argument is literal string.**
|
|
332
|
+
* @template T - The type value to check.
|
|
333
|
+
* @example
|
|
334
|
+
* type Case1 = IsStringLiteral<'a'>; // ➔ true
|
|
335
|
+
* type Case2 = IsStringLiteral<1>; // ➔ false
|
|
336
|
+
* type Case3 = IsStringLiteral<string>; // ➔ false
|
|
337
|
+
*/
|
|
338
|
+
type IsStringLiteral<T> = If<Extends<T, string>, Extends<string, T> extends true ? false : true>;
|
|
339
|
+
/** -------------------------------------------------------
|
|
340
|
+
* * ***Utility Type: `IfNot`.***
|
|
341
|
+
* -------------------------------------------------------
|
|
342
|
+
* - **Conditional:**
|
|
343
|
+
* - Returns the second argument if the first argument is `false`, otherwise returns the third argument.
|
|
344
|
+
* - Defaults: `IfTrue = true`, `IfFalse = false`.
|
|
345
|
+
* @template Condition - The boolean condition to check.
|
|
346
|
+
* @template IfTrue - The branch type if condition is `false`. (default: `true`).
|
|
347
|
+
* @template IfFalse - The branch type if condition is `true`. (default: `false`).
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* type A = IfNot<false, "valid">;
|
|
351
|
+
* // ➔ "valid"
|
|
352
|
+
* type B = IfNot<false, "valid", "invalid">;
|
|
353
|
+
* // ➔ "invalid"
|
|
354
|
+
* ```
|
|
355
|
+
*/
|
|
356
|
+
type IfNot<Condition, IfTrue = true, IfFalse = false> = If<Condition, IfFalse, IfTrue>;
|
|
357
|
+
/** -------------------------------------------------------
|
|
358
|
+
* * ***Utility Type: `WordSeparator`.***
|
|
359
|
+
* -------------------------------------------------------
|
|
360
|
+
* **A type-level utility that defines all valid ***word separators***.**
|
|
361
|
+
* - Can be a space `" "`, a dash `"-"`, or an underscore `"_"`.
|
|
362
|
+
* @example
|
|
363
|
+
* type A = WordSeparator; // ➔ " " | "-" | "_"
|
|
364
|
+
*/
|
|
365
|
+
/** --------------------------------------------------
|
|
366
|
+
* * ***Utility Type: `Whitespace`.***
|
|
367
|
+
* --------------------------------------------------
|
|
368
|
+
* **Represents common whitespace characters.**
|
|
369
|
+
* - ✅ Used as the default trimming characters in string utility types.
|
|
370
|
+
* @example
|
|
371
|
+
* type W = Whitespace; // ➔ " " | "\t" | "\r" | "\n"
|
|
372
|
+
*/
|
|
373
|
+
type Whitespace = " " | "\t" | "\r" | "\n";
|
|
374
|
+
/**
|
|
375
|
+
* **Helper Type Internal.**
|
|
376
|
+
*/
|
|
377
|
+
type SafeKeyTrimming<T> = Exclude<T, symbol>;
|
|
378
|
+
/** --------------------------------------------------
|
|
379
|
+
* * ***Utility Type: `TrimLeft`.***
|
|
380
|
+
* --------------------------------------------------
|
|
381
|
+
* **Recursively trims specified characters (default: **{@link Whitespace | `Whitespace`}**) from the **start (left)** of a string.**
|
|
382
|
+
* @template Text - The string to trim.
|
|
383
|
+
* @template Chars - The characters to remove (default: `Whitespace`).
|
|
384
|
+
* @example
|
|
385
|
+
* type T1 = TrimLeft<"\n hello", " " | "\n">;
|
|
386
|
+
* // ➔ "hello"
|
|
387
|
+
* type T2 = TrimLeft<" world">;
|
|
388
|
+
* // ➔ "world"
|
|
389
|
+
* type T3 = TrimLeft<" world ">;
|
|
390
|
+
* // ➔ "world "
|
|
391
|
+
*/
|
|
392
|
+
type TrimLeft<Text extends PropertyKey, Chars extends PropertyKey = Whitespace> = Text extends `${SafeKeyTrimming<Chars>}${infer Rest}` ? TrimLeft<Rest, Chars> : Text;
|
|
393
|
+
/** --------------------------------------------------
|
|
394
|
+
* * ***Utility Type: `TrimRight`.***
|
|
395
|
+
* --------------------------------------------------
|
|
396
|
+
* **Recursively trims specified characters (default: **{@link Whitespace | `Whitespace`}**) from the **end (right)** of a string.**
|
|
397
|
+
* @template Text - The string to trim.
|
|
398
|
+
* @template Chars - The characters to remove (default: `Whitespace`).
|
|
399
|
+
* @example
|
|
400
|
+
* type T1 = TrimRight<"hello \t", " " | "\t">;
|
|
401
|
+
* // ➔ "hello"
|
|
402
|
+
* type T2 = TrimRight<"world ">;
|
|
403
|
+
* // ➔ "world"
|
|
404
|
+
* type T2 = TrimRight<" world ">;
|
|
405
|
+
* // ➔ " world"
|
|
406
|
+
*/
|
|
407
|
+
type TrimRight<Text extends PropertyKey, Chars extends PropertyKey = Whitespace> = Text extends `${infer Rest}${SafeKeyTrimming<Chars>}` ? TrimRight<Rest, Chars> : Text;
|
|
408
|
+
/** --------------------------------------------------
|
|
409
|
+
* * ***Utility Type: `Trim`.***
|
|
410
|
+
* --------------------------------------------------
|
|
411
|
+
* **Trims specified characters (default: **{@link Whitespace | `Whitespace`}**)
|
|
412
|
+
* from **both the start and end** of a string.**
|
|
413
|
+
* @template Chars - The characters to remove (default: `Whitespace`).
|
|
414
|
+
* @example
|
|
415
|
+
* type T1 = Trim<" hello ", " ">;
|
|
416
|
+
* // ➔ "hello"
|
|
417
|
+
* type T2 = Trim<"\n world \t">;
|
|
418
|
+
* // ➔ "world"
|
|
419
|
+
*/
|
|
420
|
+
type Trim<Text extends PropertyKey, Chars extends PropertyKey = Whitespace> = TrimRight<TrimLeft<Text, Chars>, Chars>;
|
|
421
|
+
/** -------------------------------------------------------
|
|
422
|
+
* * ***Utility Type: `TrimsLower`.***
|
|
423
|
+
* -------------------------------------------------------
|
|
424
|
+
* **Trims leading & trailing whitespace from a string and
|
|
425
|
+
* converts it to **lowercase**.**
|
|
426
|
+
* @description
|
|
427
|
+
* Utilizes **{@link Trim | `Trim`}** to remove whitespace and
|
|
428
|
+
* **{@link Lowercase | `Lowercase`}** to convert the string to lowercase.
|
|
429
|
+
* @template S - The input string to transform.
|
|
430
|
+
* @example
|
|
431
|
+
* ```ts
|
|
432
|
+
* type T1 = TrimsLower<" HeLLo \n">;
|
|
433
|
+
* // ➔ "hello"
|
|
434
|
+
* type T2 = TrimsLower<" WoRLD ">;
|
|
435
|
+
* // ➔ "world"
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
/** -------------------------------------------------------
|
|
439
|
+
* * ***Utility Type: `AnyString`.***
|
|
440
|
+
* -------------------------------------------------------
|
|
441
|
+
* **A utility type that represents **any string value** while
|
|
442
|
+
* preventing unwanted widening of string literals to `string`.**
|
|
443
|
+
* @description
|
|
444
|
+
* This is achieved by intersecting `string` with `{}`,
|
|
445
|
+
* ensuring that the type remains assignable to `string`
|
|
446
|
+
* but is treated as a unique type in generic constraints.
|
|
447
|
+
* - **Useful in scenarios where:**
|
|
448
|
+
* - You want to accept **any string**, but still preserve
|
|
449
|
+
* literal types in inference.
|
|
450
|
+
* - You need stricter typing than just `string`.
|
|
451
|
+
* @example
|
|
452
|
+
* ```ts
|
|
453
|
+
* declare function acceptsAnyString<T extends AnyString>(value: T): T;
|
|
454
|
+
*
|
|
455
|
+
* // Preserves literal
|
|
456
|
+
* const a = acceptsAnyString("hello");
|
|
457
|
+
* // ➔ "hello"
|
|
458
|
+
*
|
|
459
|
+
* // Also allows generic string
|
|
460
|
+
* const b = acceptsAnyString(String("world"));
|
|
461
|
+
* // ➔ string
|
|
462
|
+
* ```
|
|
463
|
+
*/
|
|
464
|
+
type AnyString = {} & string;
|
|
465
|
+
/** -------------------------------------------------------
|
|
466
|
+
* * ***Utility Type: `EmptyString`.***
|
|
467
|
+
* -------------------------------------------------------
|
|
468
|
+
* - **Conditional type:**
|
|
469
|
+
* - Returns the type `T` only if it is the empty string `""`.
|
|
470
|
+
* - Optionally trims whitespace before checking.
|
|
471
|
+
* - **Behavior:**
|
|
472
|
+
* - If `WithTrim` is `true` (default), trims `T` before checking.
|
|
473
|
+
* - If `T` is the general `string` type, returns `never`.
|
|
474
|
+
* - If `T` is empty (after optional trimming), returns `T` or `Trim<T>`.
|
|
475
|
+
* @template T - The string type to check.
|
|
476
|
+
* @template WithTrim - Whether to trim whitespace before checking (default `true`).
|
|
477
|
+
* @example
|
|
478
|
+
* ```ts
|
|
479
|
+
* // Basic empty string
|
|
480
|
+
* type Case1 = EmptyString<"">;
|
|
481
|
+
* // ➔ ""
|
|
482
|
+
*
|
|
483
|
+
* // Non-empty string
|
|
484
|
+
* type Case2 = EmptyString<"abc">;
|
|
485
|
+
* // ➔ never
|
|
486
|
+
*
|
|
487
|
+
* // General string type
|
|
488
|
+
* type Case3 = EmptyString<string>;
|
|
489
|
+
* // ➔ never
|
|
490
|
+
*
|
|
491
|
+
* // With leading/trailing whitespace
|
|
492
|
+
* type Case4 = EmptyString<" ", true>;
|
|
493
|
+
* // ➔ "" (trimmed)
|
|
494
|
+
* type Case5 = EmptyString<" ", false>;
|
|
495
|
+
* // ➔ never (not trimmed)
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
type EmptyString<T extends string, WithTrim extends boolean = true> = "" extends (WithTrim extends true ? Trim<T> : T) ? string extends (WithTrim extends true ? Trim<T> : T) ? never : WithTrim extends true ? Trim<T> : T : never;
|
|
499
|
+
/** -------------------------------------------------------
|
|
500
|
+
* * ***Utility Type: `NonEmptyString`.***
|
|
501
|
+
* -------------------------------------------------------
|
|
502
|
+
* - **Conditional type:**
|
|
503
|
+
* - Returns the type `T` only if it is a non-empty string.
|
|
504
|
+
* - Optionally trims whitespace before checking.
|
|
505
|
+
* - **Behavior:**
|
|
506
|
+
* - If `WithTrim` is `true` (default), trims `T` before checking.
|
|
507
|
+
* - If `T` is the general `string` type, returns `string`.
|
|
508
|
+
* - If `T` is empty (after optional trimming), returns `never`.
|
|
509
|
+
* @template T - The string type to check.
|
|
510
|
+
* @template WithTrim - Whether to trim whitespace before checking (default `true`).
|
|
511
|
+
* @example
|
|
512
|
+
* ```ts
|
|
513
|
+
* // Non-empty string
|
|
514
|
+
* type Case1 = NonEmptyString<"abc">; // ➔ "abc"
|
|
515
|
+
*
|
|
516
|
+
* // Empty string
|
|
517
|
+
* type Case2 = NonEmptyString<"">; // ➔ never
|
|
518
|
+
*
|
|
519
|
+
* // General string type
|
|
520
|
+
* type Case3 = NonEmptyString<string>; // ➔ string
|
|
521
|
+
*
|
|
522
|
+
* // String with whitespace
|
|
523
|
+
* type Case4 = NonEmptyString<" ", true>; // ➔ never (trimmed to empty)
|
|
524
|
+
* type Case5 = NonEmptyString<" ", false>; // ➔ " " (not trimmed)
|
|
525
|
+
* ```
|
|
526
|
+
*/
|
|
527
|
+
/** -------------------------------------------------------
|
|
528
|
+
* * ***Utility Type: `IsEmptyString`.***
|
|
529
|
+
* -------------------------------------------------------
|
|
530
|
+
* - **Conditional type:**
|
|
531
|
+
* - Returns `true` if `T` is exactly the empty string `""`.
|
|
532
|
+
* - Optionally trims whitespace before checking.
|
|
533
|
+
* - **Behavior:**
|
|
534
|
+
* - If `WithTrim` is `true` (default), trims `T` before checking.
|
|
535
|
+
* - If `T` is empty after optional trimming, returns `true`.
|
|
536
|
+
* - Otherwise, returns `false`.
|
|
537
|
+
* @template T - The string type to check.
|
|
538
|
+
* @template WithTrim - Whether to trim whitespace before checking (default `true`).
|
|
539
|
+
* @example
|
|
540
|
+
* ```ts
|
|
541
|
+
* type Case1 = IsEmptyString<"">;
|
|
542
|
+
* // ➔ true
|
|
543
|
+
* type Case2 = IsEmptyString<"abc">;
|
|
544
|
+
* // ➔ false
|
|
545
|
+
* type Case3 = IsEmptyString<" ", true>;
|
|
546
|
+
* // ➔ true (trimmed)
|
|
547
|
+
* type Case4 = IsEmptyString<" ", false>;
|
|
548
|
+
* // ➔ false (not trimmed)
|
|
549
|
+
* ```
|
|
550
|
+
*/
|
|
551
|
+
type IsEmptyString<T extends string, WithTrim extends boolean = true> = IfNot<IsNever<EmptyString<T, WithTrim>>>;
|
|
552
|
+
/** -------------------------------------------------------
|
|
553
|
+
* * ***Utility Type: `IsNonEmptyString`.***
|
|
554
|
+
* -------------------------------------------------------
|
|
555
|
+
* - **Conditional type:**
|
|
556
|
+
* - Returns `true` if `T` is a non-empty string.
|
|
557
|
+
* - Optionally trims whitespace before checking.
|
|
558
|
+
* - **Behavior:**
|
|
559
|
+
* - If `WithTrim` is `true` (default), trims `T` before checking.
|
|
560
|
+
* - Returns `true` if `T` is non-empty after optional trimming.
|
|
561
|
+
* - Returns `false` if `T` is empty (after trimming if `WithTrim=true`).
|
|
562
|
+
* @template T - The string type to check.
|
|
563
|
+
* @template WithTrim - Whether to trim whitespace before checking (default `true`).
|
|
564
|
+
* @example
|
|
565
|
+
* ```ts
|
|
566
|
+
* type Case1 = IsNonEmptyString<"abc">;
|
|
567
|
+
* // ➔ true
|
|
568
|
+
* type Case2 = IsNonEmptyString<"">;
|
|
569
|
+
* // ➔ false
|
|
570
|
+
* type Case3 = IsNonEmptyString<" ", true>;
|
|
571
|
+
* // ➔ false (trimmed)
|
|
572
|
+
* type Case4 = IsNonEmptyString<" ", false>;
|
|
573
|
+
* // ➔ true (not trimmed)
|
|
574
|
+
* ```
|
|
575
|
+
*/
|
|
576
|
+
/** -------------------------------------------------------
|
|
577
|
+
* * ***Utility Type: `IsAny`.***
|
|
578
|
+
* -------------------------------------------------------
|
|
579
|
+
* **A type-level utility that checks whether a type is ***`any`***.**
|
|
580
|
+
* - **Behavior:**
|
|
581
|
+
* - Returns `true` if `T` is `any`.
|
|
582
|
+
* - Returns `false` for otherwise.
|
|
583
|
+
* @template T - The type to evaluate.
|
|
584
|
+
* @example
|
|
585
|
+
* ```ts
|
|
586
|
+
* type A = IsAny<any>; // ➔ true
|
|
587
|
+
* type B = IsAny<string>; // ➔ false
|
|
588
|
+
* type C = IsAny<unknown>; // ➔ false
|
|
589
|
+
* type D = IsAny<never>; // ➔ false
|
|
590
|
+
* ```
|
|
591
|
+
*/
|
|
592
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
593
|
+
/** -------------------------------------------------------
|
|
594
|
+
* * ***Utility Type: `IfAny`.***
|
|
595
|
+
* -------------------------------------------------------
|
|
596
|
+
* **A type-level conditional utility that returns one type if ***`T` is `any`***,
|
|
597
|
+
* and another type otherwise.**
|
|
598
|
+
* - **Behavior:**
|
|
599
|
+
* - Defaults to `true` when `T` is `any`.
|
|
600
|
+
* - Defaults to `false` for otherwise.
|
|
601
|
+
* @template T - The type to check.
|
|
602
|
+
* @template IfTrue - The type to return if `T` is `any`, *(default: `true`)*.
|
|
603
|
+
* @template IfFalse - The type to return if `T` is not `any`, *(default: `false`)*.
|
|
604
|
+
* @example
|
|
605
|
+
* ```ts
|
|
606
|
+
* type A = IfAny<any, string, number>;
|
|
607
|
+
* // ➔ string
|
|
608
|
+
* type B = IfAny<string, string, number>;
|
|
609
|
+
* // ➔ number
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
/** --------------------------------------------------
|
|
613
|
+
* * ***Utility Type: `AnyFunction`.***
|
|
614
|
+
* --------------------------------------------------
|
|
615
|
+
* **A generic type representing **any function** with
|
|
616
|
+
* any arguments and any return type.**
|
|
617
|
+
* @example
|
|
618
|
+
* const fn: AnyFunction = (a, b) => a + b;
|
|
619
|
+
* console.log(fn(1, 2)); // ➔ 3
|
|
620
|
+
*
|
|
621
|
+
* const fn2: AnyFunction = (x, y, z) => x + y - z;
|
|
622
|
+
* console.log(fn2(10, 20, 5)); // ➔ 25
|
|
623
|
+
*/
|
|
624
|
+
type AnyFunction = (...args: any[]) => any;
|
|
625
|
+
/** --------------------------------------------------
|
|
626
|
+
* * ***Utility Type: `ArgumentTypes`.***
|
|
627
|
+
* --------------------------------------------------
|
|
628
|
+
* **Extracts the **argument types** of a given function type `F`.**
|
|
629
|
+
* - ✅ Useful when you need to infer or reuse the parameter types
|
|
630
|
+
* from an existing function signature.
|
|
631
|
+
* @template F - A function type from which to extract argument types.
|
|
632
|
+
* @example
|
|
633
|
+
* ```ts
|
|
634
|
+
* type Args = ArgumentTypes<(a: number, b: string) => void>;
|
|
635
|
+
* // ➔ [number, string]
|
|
636
|
+
* ```
|
|
637
|
+
*/
|
|
638
|
+
/** -------------------------------------------------------
|
|
639
|
+
* * ***Utility Type: `FixNeverArrayRecursive`.***
|
|
640
|
+
* -------------------------------------------------------
|
|
641
|
+
* **A type-level utility that **recursively transforms arrays of type `never[]` into empty arrays**.**
|
|
642
|
+
* - **Behavior:**
|
|
643
|
+
* - Preserves `readonly` modifiers.
|
|
644
|
+
* - Applies recursively for nested arrays.
|
|
645
|
+
* - Leaves other types unchanged.
|
|
646
|
+
* @template T - The input type to recursively fix.
|
|
647
|
+
* @example
|
|
648
|
+
* ```ts
|
|
649
|
+
* type A = FixNeverArrayRecursive<never[]>;
|
|
650
|
+
* // ➔ []
|
|
651
|
+
* type B = FixNeverArrayRecursive<readonly never[]>;
|
|
652
|
+
* // ➔ readonly []
|
|
653
|
+
* type C = FixNeverArrayRecursive<string[]>;
|
|
654
|
+
* // ➔ string[]
|
|
655
|
+
* type D = FixNeverArrayRecursive<(never | string)[]>;
|
|
656
|
+
* // ➔ (never | string)[]
|
|
657
|
+
* type E = FixNeverArrayRecursive<(never[])[]>;
|
|
658
|
+
* // ➔ [][]
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
type FixNeverArrayRecursive<T> = T extends readonly never[] ? T extends never[] ? [] : readonly [] : T extends (infer U)[] ? FixNeverArrayRecursive<U>[] : T extends readonly (infer U)[] ? readonly FixNeverArrayRecursive<U>[] : T;
|
|
662
|
+
/** -------------------------------------------------------
|
|
663
|
+
* * ***Utility Type: `NormalizeEmptyArraysRecursive`.***
|
|
664
|
+
* -------------------------------------------------------
|
|
665
|
+
* **A type-level utility that **recursively normalizes empty array types** by converting arrays whose element type is `never`, `null`, or `undefined` into empty tuple types (`[]`).**
|
|
666
|
+
* - **Behavior:**
|
|
667
|
+
* - Preserves `readonly` modifiers.
|
|
668
|
+
* - Recurses into nested arrays.
|
|
669
|
+
* - Leaves other array types unchanged.
|
|
670
|
+
* @template T - The input type to normalize.
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* type A = NormalizeEmptyArraysRecursive<never[]>;
|
|
674
|
+
* // ➔ []
|
|
675
|
+
* type B = NormalizeEmptyArraysRecursive<readonly never[]>;
|
|
676
|
+
* // ➔ readonly []
|
|
677
|
+
* type C = NormalizeEmptyArraysRecursive<null[]>;
|
|
678
|
+
* // ➔ []
|
|
679
|
+
* type D = NormalizeEmptyArraysRecursive<(null[] | string[])[]>;
|
|
680
|
+
* // ➔ ([] | string[])[]
|
|
681
|
+
* type E = NormalizeEmptyArraysRecursive<string[]>;
|
|
682
|
+
* // ➔ string[]
|
|
683
|
+
* ```
|
|
684
|
+
*/
|
|
685
|
+
type NormalizeEmptyArraysRecursive<T> = T extends readonly (infer U)[] ? U extends never | null | undefined ? T extends readonly unknown[] ? T extends (infer _E)[] ? [] : readonly [] : never : T extends (infer _E)[] ? NormalizeEmptyArraysRecursive<U>[] : readonly NormalizeEmptyArraysRecursive<U>[] : T;
|
|
686
|
+
/** -------------------------------------------------------
|
|
687
|
+
* * ***Utility Type: `RemoveEmptyArrayElements`.***
|
|
688
|
+
* -------------------------------------------------------
|
|
689
|
+
* **A type-level utility that **recursively removes empty array elements (`[]`) from a tuple type**.**
|
|
690
|
+
* - **Behavior:**
|
|
691
|
+
* - If `T` is a tuple, checks the first element:
|
|
692
|
+
* - If `Head` is an empty array type (`[]`), it is removed.
|
|
693
|
+
* - Otherwise, `Head` is preserved.
|
|
694
|
+
* - Repeats recursively on the rest of the tuple.
|
|
695
|
+
* - Leaves non-tuple types unchanged.
|
|
696
|
+
* @template T - The tuple type to process.
|
|
697
|
+
* @example
|
|
698
|
+
* ```ts
|
|
699
|
+
* type A = RemoveEmptyArrayElements<[[], 1, [], 2]>;
|
|
700
|
+
* // ➔ [1, 2]
|
|
701
|
+
* type B = RemoveEmptyArrayElements<[]>;
|
|
702
|
+
* // ➔ []
|
|
703
|
+
* type C = RemoveEmptyArrayElements<[[], [], []]>;
|
|
704
|
+
* // ➔ []
|
|
705
|
+
* type D = RemoveEmptyArrayElements<[1, 2, 3]>;
|
|
706
|
+
* // ➔ [1, 2, 3]
|
|
707
|
+
* ```
|
|
708
|
+
*/
|
|
709
|
+
type RemoveEmptyArrayElements<T> = T extends [infer Head, ...infer Tail] ? Head extends [] ? RemoveEmptyArrayElements<Tail> : [Head, ...RemoveEmptyArrayElements<Tail>] : T extends [] ? [] : T;
|
|
710
|
+
/** ---------------------------------------------------------------------------
|
|
711
|
+
* * ***Type Options for {@link LastCharacter | `LastCharacter`}.***
|
|
712
|
+
* ---------------------------------------------------------------------------
|
|
713
|
+
*/
|
|
714
|
+
/** -------------------------------------------------------
|
|
715
|
+
* * ***Utility Type: `OrArr`.***
|
|
716
|
+
* -------------------------------------------------------
|
|
717
|
+
* **Computes the logical OR of all elements inside a tuple or array of boolean types.**
|
|
718
|
+
* @template Conditions - An array of boolean type elements.
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* type Case1 = OrArr<[true, true, true]>; // ➔ true
|
|
722
|
+
* type Case2 = OrArr<[true, true, false]>; // ➔ true
|
|
723
|
+
* type Case3 = OrArr<[false, false, false]>; // ➔ false
|
|
724
|
+
* type Case4 = OrArr<[]>; // ➔ false
|
|
725
|
+
* ```
|
|
726
|
+
* @remarks
|
|
727
|
+
* - Uses TypeScript's indexed access types and conditional type inference.
|
|
728
|
+
* - Returns `true` if at least one element in the array is `true`.
|
|
729
|
+
* - Returns `false` if all elements are `false` or array is empty.
|
|
730
|
+
*/
|
|
731
|
+
type OrArr<Conditions extends readonly unknown[]> = true extends Conditions[number] ? true : false;
|
|
732
|
+
/** -------------------------------------------------------
|
|
733
|
+
* * ***Utility Type: `Push`.***
|
|
734
|
+
* -------------------------------------------------------
|
|
735
|
+
* **Appends a type `U` to the end of a tuple or readonly array type `T`.**
|
|
736
|
+
* @template T - The tuple or readonly array type to append U.
|
|
737
|
+
* @template U - The type of the element to push.
|
|
738
|
+
* @example
|
|
739
|
+
* ```ts
|
|
740
|
+
* type Case1 = Push<[1, 2, 3, 4], 5>;
|
|
741
|
+
* // ➔ [1, 2, 3, 4, 5]
|
|
742
|
+
*
|
|
743
|
+
* type Case2 = Push<["a", "b"], "c">;
|
|
744
|
+
* // ➔ ["a", "b", "c"]
|
|
745
|
+
* ```
|
|
746
|
+
*/
|
|
747
|
+
type Push<T extends readonly unknown[], U> = [...T, U];
|
|
748
|
+
type _Repeat<T extends string, Count extends number, Result extends string = "", Iteration extends unknown[] = []> = Iteration["length"] extends Count ? Result : _Repeat<T, Count, `${T}${Result}`, Push<Iteration, unknown>>;
|
|
749
|
+
/** -------------------------------------------------------
|
|
750
|
+
* * ***Utility Type: `Repeat`.***
|
|
751
|
+
* -------------------------------------------------------
|
|
752
|
+
* **Repeats a string literal type `T` a specified number of times `Count`.**
|
|
753
|
+
* - **Behavior:**
|
|
754
|
+
* - Supports a range of `[0, 999]` due to TypeScript recursion limits.
|
|
755
|
+
* - If `Count > 999`, it is automatically to `any` because error `Type instantiation is excessively deep and possibly infinite.ts(2589)`.
|
|
756
|
+
* @template T - The string literal to repeat.
|
|
757
|
+
* @template Count - Number of times to repeat.
|
|
758
|
+
* @example
|
|
759
|
+
* ```ts
|
|
760
|
+
* type Case0 = Repeat<'x', 0>; // ➔ ''
|
|
761
|
+
* type Case1 = Repeat<'x', 1>; // ➔ 'x'
|
|
762
|
+
* type Case2 = Repeat<'x', 5>; // ➔ 'xxxxx'
|
|
763
|
+
* type Case3 = Repeat<'ab', 3>; // ➔ 'ababab'
|
|
764
|
+
*
|
|
765
|
+
* // ❌ Invalid:
|
|
766
|
+
* type Case1000 = Repeat<'x', 1000>;
|
|
767
|
+
* // ➔ same as any (because: TypeScript recursion limits)
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
type Repeat<T extends string, Count extends number> = _Repeat<T, Count>;
|
|
771
|
+
/** -------------------------------------------------------
|
|
772
|
+
* * ***Utility Type: `OddDigit`.***
|
|
773
|
+
* -------------------------------------------------------
|
|
774
|
+
* **A union of string literal digits considered ***odd***.**
|
|
775
|
+
* - Includes: `"1" | "3" | "5" | "7" | "9"`.
|
|
776
|
+
* @example
|
|
777
|
+
* ```ts
|
|
778
|
+
* type A = OddDigit; // ➔ "1" | "3" | "5" | "7" | "9"
|
|
779
|
+
* ```
|
|
780
|
+
*/
|
|
781
|
+
/** -------------------------------------------------------
|
|
782
|
+
* * ***Utility Type: `Negative`.***
|
|
783
|
+
* -------------------------------------------------------
|
|
784
|
+
* **Extracts `T` if it is ***negative***, otherwise `never`.**
|
|
785
|
+
* @template T - A number type to check.
|
|
786
|
+
* @example
|
|
787
|
+
* ```ts
|
|
788
|
+
* type A = Negative<-10>; // ➔ -10
|
|
789
|
+
* type B = Negative<5>; // ➔ never
|
|
790
|
+
* type C = Negative<0>; // ➔ never
|
|
791
|
+
* ```
|
|
792
|
+
*/
|
|
793
|
+
type Negative<T extends number> = `${T}` extends `-${string}` ? T : never;
|
|
794
|
+
/** -------------------------------------------------------
|
|
795
|
+
* * ***Utility Type: `Positive`.***
|
|
796
|
+
* -------------------------------------------------------
|
|
797
|
+
* **Extracts `T` if it is ***positive*** (or zero), otherwise `never`.**
|
|
798
|
+
* @template T - A number type to check.
|
|
799
|
+
* @example
|
|
800
|
+
* ```ts
|
|
801
|
+
* type A = Positive<10>; // ➔ 10
|
|
802
|
+
* type B = Positive<0>; // ➔ 0
|
|
803
|
+
* type C = Positive<-5>; // ➔ never
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
type Positive<T extends number> = If<IsNever<Negative<T>>, T, never>;
|
|
807
|
+
/** -------------------------------------------------------
|
|
808
|
+
* * ***Utility Type: `PositiveInteger`.***
|
|
809
|
+
* -------------------------------------------------------
|
|
810
|
+
* **Restricts `T` to ***positive integers*** only.**
|
|
811
|
+
* @template T - A number type.
|
|
812
|
+
* @example
|
|
813
|
+
* ```ts
|
|
814
|
+
* type A = PositiveInteger<42>; // ➔ 42
|
|
815
|
+
* type B = PositiveInteger<0>; // ➔ 0
|
|
816
|
+
* type C = PositiveInteger<-5>; // ➔ never
|
|
817
|
+
* type D = PositiveInteger<3.14>; // ➔ never
|
|
818
|
+
* ```
|
|
819
|
+
*/
|
|
820
|
+
/** -------------------------------------------------------
|
|
821
|
+
* * ***Utility Type: `IsPositive`.***
|
|
822
|
+
* -------------------------------------------------------
|
|
823
|
+
* **Whether `T` is ***positive***.**
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* type A = IsPositive<10>; // ➔ true
|
|
827
|
+
* type B = IsPositive<0>; // ➔ true
|
|
828
|
+
* type C = IsPositive<-5>; // ➔ false
|
|
829
|
+
* type D = IsPositive<3.5>; // ➔ true
|
|
830
|
+
* type E = IsPositive<-3.5>; // ➔ false
|
|
831
|
+
* ```
|
|
832
|
+
*/
|
|
833
|
+
type IsPositive<T extends number> = Not<IsNever<Positive<T>>>;
|
|
834
|
+
/** -------------------------------------------------------
|
|
835
|
+
* * ***Utility Type: `IsNegative`.***
|
|
836
|
+
* -------------------------------------------------------
|
|
837
|
+
* **Whether `T` is ***negative***.**
|
|
838
|
+
* @example
|
|
839
|
+
* ```ts
|
|
840
|
+
* type A = IsNegative<-10>; // ➔ true
|
|
841
|
+
* type B = IsNegative<5>; // ➔ false
|
|
842
|
+
* type C = IsNegative<0>; // ➔ false
|
|
843
|
+
* type D = IsPositive<3.5>; // ➔ false
|
|
844
|
+
* type E = IsPositive<-3.5>; // ➔ true
|
|
845
|
+
* ```
|
|
846
|
+
*/
|
|
847
|
+
/** -------------------------------------------------------
|
|
848
|
+
* * ***Utility Type: `ParseNumber`.***
|
|
849
|
+
* --------------------------------------------------------
|
|
850
|
+
* **Converts a string or property key literal into a ***number literal***.**
|
|
851
|
+
* - **Behavior:**
|
|
852
|
+
* - Supports decimal numbers only.
|
|
853
|
+
* - Automatically trims whitespace.
|
|
854
|
+
* - Returns the number literal if valid.
|
|
855
|
+
* - Supports scientific notation strings (e.g., `"2e-3"`, `"-5e2"`, `"2E-3"`, `"-5E2"`).
|
|
856
|
+
* - **Note:**
|
|
857
|
+
* - TypeScript cannot represent very small (`< 1e-6`) or very large (`> 1e15`)
|
|
858
|
+
* numbers as literal types:
|
|
859
|
+
* - In such cases, scientific notation strings return `0`.
|
|
860
|
+
* - Returns `0` for strings representing hexadecimal (`0x...`), octal (`0o...`), or
|
|
861
|
+
* binary (`0b...`) if they are string literals.
|
|
862
|
+
* - Returns `never` for non-numeric strings or unsupported formats.
|
|
863
|
+
* @template T - A string, number, or symbol (property key).
|
|
864
|
+
* @example
|
|
865
|
+
* ```ts
|
|
866
|
+
* // Number:
|
|
867
|
+
* type A = ParseNumber<0>; // ➔ 0
|
|
868
|
+
* type B = ParseNumber<-0>; // ➔ 0
|
|
869
|
+
* type C = ParseNumber<-0.>; // ➔ 0
|
|
870
|
+
* type D = ParseNumber<42>; // ➔ 42
|
|
871
|
+
* type E = ParseNumber<0.42>; // ➔ 0.42
|
|
872
|
+
* type F = ParseNumber<-5>; // ➔ -5
|
|
873
|
+
* type G = ParseNumber<-2.5>; // ➔ -2.5
|
|
874
|
+
* type H = ParseNumber<2.5e3>; // ➔ 2500
|
|
875
|
+
* type I = ParseNumber<-2.5e3>;// ➔ -2500
|
|
876
|
+
* type J = ParseNumber<5e3>; // ➔ 5000
|
|
877
|
+
* type K = ParseNumber<-5e3>; // ➔ -5000
|
|
878
|
+
* type L = ParseNumber<5e21>; // ➔ 5e+21
|
|
879
|
+
* type M = ParseNumber<5e-3>; // ➔ 0.005
|
|
880
|
+
* type N = ParseNumber<5e-21>; // ➔ 5e-21
|
|
881
|
+
* type O = ParseNumber<-5e-3>; // ➔ -0.005
|
|
882
|
+
*
|
|
883
|
+
* // Numeric String:
|
|
884
|
+
* type A = ParseNumber<"0">; // ➔ 0
|
|
885
|
+
* type B = ParseNumber<"-0">; // ➔ 0
|
|
886
|
+
* type C = ParseNumber<"42">; // ➔ 42
|
|
887
|
+
* type D = ParseNumber<"0.42">; // ➔ 0.42
|
|
888
|
+
* type E = ParseNumber<"-42">; // ➔ -42
|
|
889
|
+
* type F = ParseNumber<"-0.42">; // ➔ -0.42
|
|
890
|
+
* type G = ParseNumber<" 42 ">; // ➔ 42
|
|
891
|
+
* type H = ParseNumber<" -42 ">; // ➔ -1
|
|
892
|
+
*
|
|
893
|
+
* // Scientific notation string:
|
|
894
|
+
* type S1 = ParseNumber<"2e3">; // ➔ 2000
|
|
895
|
+
* type S2 = ParseNumber<"-2e3">; // ➔ -2000
|
|
896
|
+
* type S3 = ParseNumber<"2e-3">; // ➔ 0.002
|
|
897
|
+
* type S4 = ParseNumber<"-2e-3">; // ➔ -0.002
|
|
898
|
+
* type S5 = ParseNumber<"2.5e3">; // ➔ 0
|
|
899
|
+
* type S6 = ParseNumber<"2.5e-3">; // ➔ 0
|
|
900
|
+
* type S7 = ParseNumber<"2e-7">; // ➔ 0 (too small include "-2e-7" for TypeScript literal)
|
|
901
|
+
* type S8 = ParseNumber<"5e21">; // ➔ 0 (too large include "-5e21" for TypeScript literal)
|
|
902
|
+
*
|
|
903
|
+
* // Number representing hexadecimal, octal or binary:
|
|
904
|
+
* type A = ParseNumber<"011">; // ➔ 9 (same as octal but deprecated)
|
|
905
|
+
* type B = ParseNumber<"0o11">; // ➔ 9 (octal)
|
|
906
|
+
* type C = ParseNumber<"-0o11">; // ➔ -9 (octal)
|
|
907
|
+
* type D = ParseNumber<"0x12">; // ➔ 18 (hexadecimal)
|
|
908
|
+
* type E = ParseNumber<"-0x12">; // ➔ -18 (hexadecimal)
|
|
909
|
+
* type F = ParseNumber<"0b111">; // ➔ 7 (binary)
|
|
910
|
+
* type G = ParseNumber<"-0b111">; // ➔ -7 (binary)
|
|
911
|
+
*
|
|
912
|
+
* // String representing hexadecimal, octal or binary:
|
|
913
|
+
* type A = ParseNumber<"0x2A">; // ➔ 0 (hex on string not supported)
|
|
914
|
+
* type B = ParseNumber<"0o52">; // ➔ 0 (octal on string not supported)
|
|
915
|
+
* type C = ParseNumber<"0b101010">; // ➔ 0 (binary on string not supported)
|
|
916
|
+
*
|
|
917
|
+
* // Never Result
|
|
918
|
+
* type A = ParseNumber<string>; // ➔ never
|
|
919
|
+
* type B = ParseNumber<number>; // ➔ never
|
|
920
|
+
* type C = ParseNumber<"abc">; // ➔ never
|
|
921
|
+
* type D = ParseNumber<"a1">; // ➔ never
|
|
922
|
+
* type E = ParseNumber<"3b">; // ➔ never
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
type ParseNumber<T extends PropertyKey | bigint> = T extends bigint ? T : If<number extends T ? false : true, IfExtends<OrArr<[Extends<"-0", Trim<Extract<T, PropertyKey>>>, Extends<-0, T>, Extends<T, `${"-" | ""}${"0"}.`>]>, true, 0, T extends `${"-" | ""}0${"x" | "b" | "o"}${number}` ? 0 : Trim<Extract<T, PropertyKey>> extends `${infer NumT extends number | string}` ? T extends `${infer N extends number}.` ? N : NumT extends string ? ParseScientificNumber<NumT> : NumT : Trim<Extract<T, PropertyKey>> extends number ? T : never>, never>;
|
|
926
|
+
/** -------------------------------------------------------
|
|
927
|
+
* * ***Utility Type: `IsScientificNumber`.***
|
|
928
|
+
* -------------------------------------------------------
|
|
929
|
+
* **Checks if a string literal `T` represents a **scientific number**.**
|
|
930
|
+
* - **A scientific number is defined as a number in the form of:**
|
|
931
|
+
* - Optional negative sign (`-`).
|
|
932
|
+
* - Mantissa (digits, can be integer or decimal).
|
|
933
|
+
* - Exponent indicated by `e` or `E`.
|
|
934
|
+
* - Exponent value (digits, optional negative sign).
|
|
935
|
+
* - **Important:**
|
|
936
|
+
* - TypeScript cannot detect numeric literals in scientific notation
|
|
937
|
+
* at type-level because number literals are normalized to decimals:
|
|
938
|
+
* - Only string literals like `"2.5E3"` or `"-1e-5"` can be detected.
|
|
939
|
+
* @template T - A string literal to check.
|
|
940
|
+
* @example
|
|
941
|
+
* ```ts
|
|
942
|
+
* type A = IsScientificNumber<"1e5">; // ➔ true
|
|
943
|
+
* type B = IsScientificNumber<"-1e-5">; // ➔ true
|
|
944
|
+
* type C = IsScientificNumber<"2.5E3">; // ➔ true
|
|
945
|
+
* type D = IsScientificNumber<"42">; // ➔ false
|
|
946
|
+
* type E = IsScientificNumber<"-0.42">; // ➔ false
|
|
947
|
+
* type F = IsScientificNumber<string>; // ➔ false
|
|
948
|
+
* ```
|
|
949
|
+
* @remarks
|
|
950
|
+
* - Uses template literal types and conditional type {@link Extends | **`Extends`**}.
|
|
951
|
+
* - Returns `true` if `T` is scientific number string literal, otherwise `false`.
|
|
952
|
+
* - Returns `boolean` if `T` is generic `string`.
|
|
953
|
+
*/
|
|
954
|
+
/** * ***Helper for {@link ParseScientificNumber | **`ParseScientificNumber`**}.***
|
|
955
|
+
*
|
|
956
|
+
*/
|
|
957
|
+
type BuildTuple<L extends number, T extends unknown[] = []> = T["length"] extends L ? T : BuildTuple<L, [...T, unknown]>;
|
|
958
|
+
/** * ***Helper for {@link ParseScientificNumber | **`ParseScientificNumber`**}.***
|
|
959
|
+
*
|
|
960
|
+
*/
|
|
961
|
+
type _DecrementParseScientific<N extends number> = BuildTuple<N> extends [infer _, ...infer Rest] ? Rest["length"] : never;
|
|
962
|
+
/** -------------------------------------------------------
|
|
963
|
+
* * ***Utility Type: `ParseScientificNumber`.***
|
|
964
|
+
* -------------------------------------------------------
|
|
965
|
+
* **Converts a numeric string in scientific notation (e.g., `"2e-3"`, `"-5e2"`)
|
|
966
|
+
* into a literal number type.**
|
|
967
|
+
* - **Important:**
|
|
968
|
+
* - TypeScript cannot represent very small or very large numbers
|
|
969
|
+
* as literal types:
|
|
970
|
+
* - In such cases, this utility will return `0`.
|
|
971
|
+
* @template T - A numeric string to parse. Can be in:
|
|
972
|
+
* - Positive or negative scientific notation (e.g., `"1e3"`, `"-2e-2"`).
|
|
973
|
+
* - Regular number literal (e.g., `"42"`, `"-5"`).
|
|
974
|
+
* @example
|
|
975
|
+
* ```ts
|
|
976
|
+
* type A1 = ParseScientificNumber<"2e-3">; // ➔ 0.002
|
|
977
|
+
* type A2 = ParseScientificNumber<"-2e-3">; // ➔ -0.002
|
|
978
|
+
* type A3 = ParseScientificNumber<"5e2">; // ➔ 500
|
|
979
|
+
* type A4 = ParseScientificNumber<"-5e2">; // ➔ -500
|
|
980
|
+
* type A5 = ParseScientificNumber<"2e-7">; // ➔ 0 (TypeScript cannot represent literal)
|
|
981
|
+
* type A6 = ParseScientificNumber<"5e21">; // ➔ 0 (TypeScript cannot represent literal)
|
|
982
|
+
* type A7 = ParseScientificNumber<"42">; // ➔ 42
|
|
983
|
+
* type A8 = ParseScientificNumber<"-42">; // ➔ -42
|
|
984
|
+
* ```
|
|
985
|
+
* @remarks
|
|
986
|
+
* - Uses type-level string manipulation to handle scientific notation.
|
|
987
|
+
* - Negative exponents are adjusted with {@link _DecrementParseScientific | **`_DecrementParseScientific`**} and
|
|
988
|
+
* {@link Repeat | **`Repeat`**}.
|
|
989
|
+
* - Returns `0` if TypeScript cannot infer the exact numeric literal.
|
|
990
|
+
*/
|
|
991
|
+
type ParseScientificNumber<T extends string> = T extends `-${infer Mantissa}${"e" | "E"}-${infer Exp extends number}` ? `-${"0."}${Repeat<"0", _DecrementParseScientific<Exp>>}${Mantissa}` extends `${infer N extends number}` ? number extends N ? 0 : N : never : T extends `${infer Mantissa}${"e" | "E"}-${infer Exp extends number}` ? `0.${Repeat<"0", _DecrementParseScientific<Exp>>}${Mantissa}` extends `${infer N extends number}` ? number extends N ? 0 : N : never : T extends `-${infer Mantissa}${"e" | "E"}${infer Exp extends number}` ? `-${Mantissa}${Repeat<"0", Exp>}` extends `${infer N extends number}` ? number extends N ? 0 : N : never : T extends `${infer Mantissa}${"e" | "E"}${infer Exp extends number}` ? `${Mantissa}${Repeat<"0", Exp>}` extends `${infer N extends number}` ? number extends N ? 0 : N : never : T extends `${infer N extends number}` ? number extends N ? 0 : N : never;
|
|
992
|
+
/** -------------------------------------------------------
|
|
993
|
+
* * ***Utility Type: `Abs`.***
|
|
994
|
+
* -------------------------------------------------------
|
|
995
|
+
* **Computes the ***absolute value*** of `T`.**
|
|
996
|
+
* - **Behavior:**
|
|
997
|
+
* - Accepts `number` literals or numeric `string` literals.
|
|
998
|
+
* - Returns the ***absolute value*** as a `number`.
|
|
999
|
+
* - If `T` is not a valid number, ***`like`***:
|
|
1000
|
+
* - `hex`, `binary`, `octal`, or `non-numeric string` will return `never`.
|
|
1001
|
+
* @template T - A number type or string literal representing a number.
|
|
1002
|
+
* @example
|
|
1003
|
+
* ```ts
|
|
1004
|
+
* type A = Abs<-42>; // ➔ 42
|
|
1005
|
+
* type B = Abs<10>; // ➔ 10
|
|
1006
|
+
* type C = Abs<"11">; // ➔ 11
|
|
1007
|
+
* type D = Abs<"-11">; // ➔ 11
|
|
1008
|
+
*
|
|
1009
|
+
* // Not a number
|
|
1010
|
+
* type Invalid1 = Abs<"1a">; // ➔ never
|
|
1011
|
+
* type Invalid2 = Abs<"a1">; // ➔ never
|
|
1012
|
+
* type Invalid3 = Abs<"a1a">; // ➔ never
|
|
1013
|
+
* type Invalid4 = Abs<"abc">; // ➔ never
|
|
1014
|
+
* type Invalid5 = Abs<string>; // ➔ never
|
|
1015
|
+
* type Invalid6 = Abs<number>; // ➔ never
|
|
1016
|
+
* ```
|
|
1017
|
+
*/
|
|
1018
|
+
/** -------------------------------------------------------
|
|
1019
|
+
* * ***Utility Type: `Stringify`.***
|
|
1020
|
+
* -------------------------------------------------------
|
|
1021
|
+
* **Converts a value of type `number`, `boolean`, `string`, `bigint`, `undefined`, or `null` into a string literal type.**
|
|
1022
|
+
* - **Behavior:**
|
|
1023
|
+
* - `number` ➔ string representation (e.g., `123` ➔ `"123"`)
|
|
1024
|
+
* - `boolean` ➔ `"true"` or `"false"`
|
|
1025
|
+
* - `string` ➔ itself
|
|
1026
|
+
* - `bigint` ➔ string representation with `"n"` suffix (e.g., `123n` ➔ `"123n"`)
|
|
1027
|
+
* - `undefined` ➔ `"undefined"`
|
|
1028
|
+
* - `null` ➔ `"null"`
|
|
1029
|
+
* - Other types ➔ `never`
|
|
1030
|
+
* @template T - The value type to stringify.
|
|
1031
|
+
* @example
|
|
1032
|
+
* ```ts
|
|
1033
|
+
* // Boolean
|
|
1034
|
+
* type Result1 = Stringify<true>;
|
|
1035
|
+
* // ➔ "true"
|
|
1036
|
+
*
|
|
1037
|
+
* // Number
|
|
1038
|
+
* type Result2 = Stringify<123>;
|
|
1039
|
+
* // ➔ "123"
|
|
1040
|
+
*
|
|
1041
|
+
* // BigInt
|
|
1042
|
+
* type Result3 = Stringify<123n>;
|
|
1043
|
+
* // ➔ "123n"
|
|
1044
|
+
*
|
|
1045
|
+
* // String
|
|
1046
|
+
* type Result4 = Stringify<"hello">;
|
|
1047
|
+
* // ➔ "hello"
|
|
1048
|
+
*
|
|
1049
|
+
* // Undefined
|
|
1050
|
+
* type Result5 = Stringify<undefined>;
|
|
1051
|
+
* // ➔ "undefined"
|
|
1052
|
+
*
|
|
1053
|
+
* // Null
|
|
1054
|
+
* type Result6 = Stringify<null>;
|
|
1055
|
+
* // ➔ "null"
|
|
1056
|
+
*
|
|
1057
|
+
* // Other type
|
|
1058
|
+
* type Result7 = Stringify<{}>;
|
|
1059
|
+
* // ➔ never
|
|
1060
|
+
* ```
|
|
1061
|
+
*/
|
|
1062
|
+
type Stringify<T> = T extends number | boolean | string | bigint | undefined | null ? T extends bigint ? `${T}n` : `${T}` : never;
|
|
1063
|
+
/** -------------------------------------------------------
|
|
1064
|
+
* * ***Utility Type: `Split`***
|
|
1065
|
+
* -------------------------------------------------------
|
|
1066
|
+
* **A type-level utility that mimics `String.prototype.split()`.**
|
|
1067
|
+
* @description
|
|
1068
|
+
* Splits a string literal `Str` into a tuple of substrings,
|
|
1069
|
+
* using `Del` as the delimiter.
|
|
1070
|
+
* - **Behavior:**
|
|
1071
|
+
* - If `Del` is the empty string `""`, the result is a tuple of characters.
|
|
1072
|
+
* - If `Del` is not found in `Str`, the result is a tuple with the original string.
|
|
1073
|
+
* - Works only with string literals. If `Str` is just `string`, the result is `string[]`.
|
|
1074
|
+
* @template Str - The input string literal to be split.
|
|
1075
|
+
* @template Del - The delimiter used to split the string.
|
|
1076
|
+
* Defaults to `""` (character-level split).
|
|
1077
|
+
* @constraints
|
|
1078
|
+
* - `Str` must be a string literal to get precise results.
|
|
1079
|
+
* - `Del` can be a string or number (numbers are converted to strings).
|
|
1080
|
+
* @example
|
|
1081
|
+
* ```ts
|
|
1082
|
+
* // ✅ Split into characters
|
|
1083
|
+
* type A = Split<"abc">; // ➔ ["a", "b", "c"]
|
|
1084
|
+
*
|
|
1085
|
+
* // ✅ Split by a comma
|
|
1086
|
+
* type B = Split<"a,b,c", ",">; // ➔ ["a", "b", "c"]
|
|
1087
|
+
*
|
|
1088
|
+
* // ✅ Split by multi-char delimiter
|
|
1089
|
+
* type C = Split<"2025-08-22", "-">; // ➔ ["2025", "08", "22"]
|
|
1090
|
+
*
|
|
1091
|
+
* // ✅ Delimiter not found ➔ returns whole string
|
|
1092
|
+
* type D = Split<"hello", "|">; // ➔ ["hello"]
|
|
1093
|
+
*
|
|
1094
|
+
* // ⚠️ Non-literal string
|
|
1095
|
+
* type E = Split<string, ",">; // string[]
|
|
1096
|
+
* ```
|
|
1097
|
+
*/
|
|
1098
|
+
type Split<Str extends string, Del extends string | number = ""> = string extends Str ? string[] : "" extends Str ? [] : Str extends `${infer T}${Del}${infer U}` ? [T, ...Split<U, Del>] : [Str];
|
|
1099
|
+
/** @private ***types for {@link CharAt}.***
|
|
1100
|
+
*
|
|
1101
|
+
*/
|
|
1102
|
+
type _CharAt<I extends string, N extends number | `${number}`, _S extends string[] = Split<I, "">> = IfExtends<And<Extends<IsPositive<ParseNumber<N>>, true>, Extends<And<Extends<N, keyof _S>, Extends<IsStringLiteral<I>, true>>, true>>, true, _S[Extract<N, keyof _S>], undefined>;
|
|
1103
|
+
/** -------------------------------------------------------
|
|
1104
|
+
* * ***Utility Type: `CharAt`.***
|
|
1105
|
+
* -------------------------------------------------------
|
|
1106
|
+
* **A type-level utility that extracts the character at a given index `N`
|
|
1107
|
+
* from a string literal type `I`.**
|
|
1108
|
+
* - **Behavior:**
|
|
1109
|
+
* - If the index is out of range, the result is `undefined`.
|
|
1110
|
+
* - If `I` is not a literal string (just `string`), the result is `undefined`.
|
|
1111
|
+
* - Only **positive indices** are supported (`0` and above`).
|
|
1112
|
+
* @template I - The input string literal to extract the character from.
|
|
1113
|
+
* @template N - The zero-based index of the character to retrieve.
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```ts
|
|
1116
|
+
* // ✅ Basic usage
|
|
1117
|
+
* type A = CharAt<"hello", 0>; // ➔ "h"
|
|
1118
|
+
* type B = CharAt<"hello", 1>; // ➔ "e"
|
|
1119
|
+
* type C = CharAt<"hello", 4>; // ➔ "o"
|
|
1120
|
+
*
|
|
1121
|
+
* // ⚠️ Index out of range ➔ undefined
|
|
1122
|
+
* type D = CharAt<"hello", 5>; // ➔ undefined
|
|
1123
|
+
* type E = CharAt<"abc", 99>; // ➔ undefined
|
|
1124
|
+
*
|
|
1125
|
+
* // ✅ Stringified index also works
|
|
1126
|
+
* type F = CharAt<"testing", "0">; // ➔ "t"
|
|
1127
|
+
* type G = CharAt<"testing", "2">; // ➔ "s"
|
|
1128
|
+
* type H = CharAt<"testing", "6">; // ➔ "g"
|
|
1129
|
+
* type I = CharAt<"testing", "7">; // ➔ undefined
|
|
1130
|
+
*
|
|
1131
|
+
* // ⚠️ Non-literal strings ➔ undefined
|
|
1132
|
+
* type J = CharAt<string, 2>; // ➔ undefined
|
|
1133
|
+
*
|
|
1134
|
+
* // ⚠️ Negative indices are not supported
|
|
1135
|
+
* type K = CharAt<"abc", -1>; // ➔ undefined
|
|
1136
|
+
* ```
|
|
1137
|
+
*/
|
|
1138
|
+
type CharAt<I extends string, N extends number | `${number}`> = _CharAt<I, N>;
|
|
1139
|
+
/** -------------------------------------------------------
|
|
1140
|
+
* * ***Utility Type: `ColorCssNamed`.***
|
|
1141
|
+
* -------------------------------------------------------
|
|
1142
|
+
* **Represents a **named CSS color keyword**, including `transparent`.**
|
|
1143
|
+
* @description
|
|
1144
|
+
* This type includes all standard color names defined in the CSS Color Module Level 4
|
|
1145
|
+
* specification, and ensures type safety for string values in strongly typed UI libraries,
|
|
1146
|
+
* themes, or design systems.
|
|
1147
|
+
* - **Behavior:**
|
|
1148
|
+
* - Only recognized, browser-supported named colors are allowed.
|
|
1149
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/named-color
|
|
1150
|
+
* @see https://drafts.csswg.org/css-color-4/#named-colors
|
|
1151
|
+
* @example
|
|
1152
|
+
* ```ts
|
|
1153
|
+
* const textColor1: ColorCssNamed = "rebeccapurple"; // ➔ ✅ valid
|
|
1154
|
+
* const textColor2: ColorCssNamed = "navy"; // ➔ ✅ valid
|
|
1155
|
+
* const textColor3: ColorCssNamed = "superblue"; // ➔ ❌ Type error
|
|
1156
|
+
*
|
|
1157
|
+
* // Usage in a theme object
|
|
1158
|
+
* const theme: Record<string, ColorCssNamed> = {
|
|
1159
|
+
* primary: "blue",
|
|
1160
|
+
* secondary: "goldenrod",
|
|
1161
|
+
* highlight: "transparent",
|
|
1162
|
+
* };
|
|
1163
|
+
* ```
|
|
1164
|
+
*/
|
|
1165
|
+
declare global {
|
|
1166
|
+
namespace NodeJS {
|
|
1167
|
+
interface EventEmitter {}
|
|
1168
|
+
interface ReadableStream {}
|
|
1169
|
+
interface WritableStream {}
|
|
1170
|
+
interface Process {}
|
|
1171
|
+
}
|
|
1172
|
+
interface Buffer {}
|
|
1173
|
+
}
|
|
1174
|
+
type Global<K extends PropertyKey> = K extends keyof typeof globalThis ? (typeof globalThis)[K] : never;
|
|
1175
|
+
type Empty<T> = keyof T extends never ? never : T;
|
|
1176
|
+
/** --------------------------------------------------
|
|
1177
|
+
* * ***Utility Type: `NodeBuiltins`.***
|
|
1178
|
+
* --------------------------------------------------
|
|
1179
|
+
* Represents commonly used Node.js runtime objects
|
|
1180
|
+
* when Node.js type definitions are available.
|
|
1181
|
+
*
|
|
1182
|
+
* @description
|
|
1183
|
+
* Includes frequently encountered Node.js core objects
|
|
1184
|
+
* and runtime-related built-ins.
|
|
1185
|
+
*
|
|
1186
|
+
* - **Examples:**
|
|
1187
|
+
* - `Buffer`
|
|
1188
|
+
* - `EventEmitter`
|
|
1189
|
+
* - `ReadableStream`
|
|
1190
|
+
* - `WritableStream`
|
|
1191
|
+
* - `process`
|
|
1192
|
+
* - `URL`
|
|
1193
|
+
*
|
|
1194
|
+
* - ❌ Excludes:
|
|
1195
|
+
* - Plain objects (`{}`)
|
|
1196
|
+
* - Primitive values
|
|
1197
|
+
* - Most Node.js modules/classes
|
|
1198
|
+
*
|
|
1199
|
+
* - ⚠️ Notes:
|
|
1200
|
+
* - This type is intentionally **not exhaustive**.
|
|
1201
|
+
* - Missing Node.js types automatically resolve to `never`.
|
|
1202
|
+
* - `URL` is always included because it exists in both
|
|
1203
|
+
* browser and Node.js environments.
|
|
1204
|
+
*/
|
|
1205
|
+
type NodeBuiltins = Empty<Global<"Buffer">> | Empty<NodeJS.EventEmitter> | Empty<NodeJS.ReadableStream> | Empty<NodeJS.WritableStream> | Empty<NodeJS.Process> | URL;
|
|
1206
|
+
/** --------------------------------------------------
|
|
1207
|
+
* * ***Utility Type: `DataTypes`.***
|
|
1208
|
+
* --------------------------------------------------
|
|
1209
|
+
* **Represents a broad union of commonly used JavaScript data types.**
|
|
1210
|
+
* - ✅ ***Includes:***
|
|
1211
|
+
* - `Primitive-Types`.
|
|
1212
|
+
* - `object`.
|
|
1213
|
+
* - `null`.
|
|
1214
|
+
* - `undefined`.
|
|
1215
|
+
* - `symbol`.
|
|
1216
|
+
* - `Any-Function` signature.
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```ts
|
|
1219
|
+
* function isValidType(value: DataTypes): boolean {
|
|
1220
|
+
* return value !== undefined && value !== null;
|
|
1221
|
+
* }
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
/** --------------------------------------------------
|
|
1225
|
+
* * ***Utility Type: `TypedArray`.***
|
|
1226
|
+
* --------------------------------------------------
|
|
1227
|
+
* **Represents all JavaScript **TypedArray** types used for binary data manipulation.**
|
|
1228
|
+
* - ✅ ***Includes:***
|
|
1229
|
+
* - `Int8Array`.
|
|
1230
|
+
* - `Uint8Array`.
|
|
1231
|
+
* - `Uint8ClampedArray`.
|
|
1232
|
+
* - `Int16Array`.
|
|
1233
|
+
* - `Uint16Array`.
|
|
1234
|
+
* - `Int32Array`.
|
|
1235
|
+
* - `Uint32Array`.
|
|
1236
|
+
* - `Float32Array`.
|
|
1237
|
+
* - `Float64Array`.
|
|
1238
|
+
* - `BigInt64Array`.
|
|
1239
|
+
* - `BigUint64Array`.
|
|
1240
|
+
*/
|
|
1241
|
+
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
|
|
1242
|
+
/** --------------------------------------------------
|
|
1243
|
+
* * ***Utility Type: `WebApiObjects`.***
|
|
1244
|
+
* --------------------------------------------------
|
|
1245
|
+
* **Represents common **Web API objects** available in the browser.**
|
|
1246
|
+
* - ✅ ***Includes:***
|
|
1247
|
+
* - URL: `URL`, `URLSearchParams`.
|
|
1248
|
+
* - Networking: `Request`, `Response`, `Headers`, `WebSocket`.
|
|
1249
|
+
* - Streams: `ReadableStream`, `WritableStream`, `TransformStream`.
|
|
1250
|
+
* - Events: `Event`, `CustomEvent`, `MessageChannel`, `MessagePort`, `MessageEvent`.
|
|
1251
|
+
* - DOM: `HTMLElement`, `Node`, `Document`, `Window`, `CanvasRenderingContext2D`.
|
|
1252
|
+
* - Encoding: `TextEncoder`, `TextDecoder`.
|
|
1253
|
+
* - File: `File`, `FileList`, `ImageBitmap`, `FormData`.
|
|
1254
|
+
* - Abort: `AbortController`, `AbortSignal`.
|
|
1255
|
+
* - Crypto: `CryptoKey`.
|
|
1256
|
+
*/
|
|
1257
|
+
type WebApiObjects = URL | URLSearchParams | FormData | Headers | Response | Request | ReadableStream<any> | WritableStream<any> | TransformStream<any, any> | MessageChannel | MessagePort | MessageEvent | Event | CustomEvent | HTMLElement | Node | Document | Window | AbortController | AbortSignal | TextEncoder | TextDecoder | CryptoKey | File | FileList | ImageBitmap | CanvasRenderingContext2D | WebSocket;
|
|
1258
|
+
/** --------------------------------------------------
|
|
1259
|
+
* * ***Utility Type: `IntlObjects`.***
|
|
1260
|
+
* --------------------------------------------------
|
|
1261
|
+
* **Represents all **ECMAScript Internationalization API** objects from `Intl`.**
|
|
1262
|
+
* - ✅ ***Includes:***
|
|
1263
|
+
* - `Intl.Collator`.
|
|
1264
|
+
* - `Intl.DateTimeFormat`.
|
|
1265
|
+
* - `Intl.NumberFormat`.
|
|
1266
|
+
* - `Intl.RelativeTimeFormat`.
|
|
1267
|
+
* - `Intl.PluralRules`.
|
|
1268
|
+
* - `Intl.ListFormat`. (if environment is supported).
|
|
1269
|
+
* - `Intl.Locale`. (if environment is supported).
|
|
1270
|
+
*/
|
|
1271
|
+
type IntlObjects = { [K in keyof typeof Intl]: (typeof Intl)[K] extends (abstract new (...args: any[]) => infer R) ? R : never }[keyof typeof Intl];
|
|
1272
|
+
/** --------------------------------------------------
|
|
1273
|
+
* * ***Utility Type: `BoxedPrimitivesTypes`.***
|
|
1274
|
+
* --------------------------------------------------
|
|
1275
|
+
* **Represents JavaScript **boxed primitive objects** (object wrappers for primitive values).**
|
|
1276
|
+
* @description
|
|
1277
|
+
* Boxed primitives are created using the `new` keyword on primitive wrapper constructors.
|
|
1278
|
+
* - ✅ ***Includes (object wrappers):***
|
|
1279
|
+
* - `new Number(123)` ➔ `Number`.
|
|
1280
|
+
* - `new String("hello")` ➔ `String`.
|
|
1281
|
+
* - `new Boolean(true)` ➔ `Boolean`.
|
|
1282
|
+
* - ❌ ***Excludes (primitive values):***
|
|
1283
|
+
* - `123` ➔ `number`.
|
|
1284
|
+
* - `"hello"` ➔ `string`.
|
|
1285
|
+
* - `true` ➔ `boolean`.
|
|
1286
|
+
* - ℹ️ ***Note:***
|
|
1287
|
+
* - These are **rarely used directly** in modern **JavaScript/TypeScript**.
|
|
1288
|
+
* - However, they exist for completeness and are sometimes relevant
|
|
1289
|
+
* when distinguishing between **primitive values** and **object wrappers**.
|
|
1290
|
+
* @example
|
|
1291
|
+
* ```ts
|
|
1292
|
+
* const a: BoxedPrimitivesTypes = new Number(123);
|
|
1293
|
+
* // ➔ ✅ valid
|
|
1294
|
+
* const b: BoxedPrimitivesTypes = new String("abc");
|
|
1295
|
+
* // ➔ ✅ valid
|
|
1296
|
+
* const c: BoxedPrimitivesTypes = new Boolean(false);
|
|
1297
|
+
* // ➔ ✅ valid
|
|
1298
|
+
*
|
|
1299
|
+
* // ❌ Not allowed (primitive values):
|
|
1300
|
+
* const x: BoxedPrimitivesTypes = 123;
|
|
1301
|
+
* const y: BoxedPrimitivesTypes = "abc";
|
|
1302
|
+
* const z: BoxedPrimitivesTypes = true;
|
|
1303
|
+
* ```
|
|
1304
|
+
*/
|
|
1305
|
+
type BoxedPrimitivesTypes = Number | String | Boolean;
|
|
1306
|
+
/** --------------------------------------------------
|
|
1307
|
+
* * ***Utility Type: `NonPlainObject`.***
|
|
1308
|
+
* --------------------------------------------------
|
|
1309
|
+
* **Represents all known **non-plain object types**,
|
|
1310
|
+
* i.e., values that are **not** considered a `"plain object"` (`{ [key: string]: any }`).**
|
|
1311
|
+
* - ✅ ***Includes:***
|
|
1312
|
+
* - **Functions**.
|
|
1313
|
+
* - **Arrays**.
|
|
1314
|
+
* - **Native objects:** `Date`, `RegExp`, `Map`, `Set`, `WeakMap`, `WeakSet`.
|
|
1315
|
+
* - **Built-in classes & APIs:** `Promise`, `Error`, `ArrayBuffer`, `DataView`.
|
|
1316
|
+
* - **Typed arrays:** `TypedArray`.
|
|
1317
|
+
* - **Browser & Node APIs:** `WebApiObjects`, `IntlObjects`, `NodeBuiltins`.
|
|
1318
|
+
* - **Symbols**.
|
|
1319
|
+
* - **Proxies** (wrapping any object).
|
|
1320
|
+
* - The global **`Reflect`** object.
|
|
1321
|
+
* - ❌ ***Excludes:***
|
|
1322
|
+
* - Plain objects (`{ foo: string }`, `Record<string, any>`), `null` and `undefined`.
|
|
1323
|
+
* - ℹ️ ***Note:***
|
|
1324
|
+
* - Use this type when you need to differentiate **plain objects** from **all other object-like values**.
|
|
1325
|
+
* @example
|
|
1326
|
+
* ```ts
|
|
1327
|
+
* type A = NonPlainObject;
|
|
1328
|
+
*
|
|
1329
|
+
* const x: A = new Date();
|
|
1330
|
+
* // ➔ ✅ Allowed
|
|
1331
|
+
* const y: A = [1, 2, 3];
|
|
1332
|
+
* // ➔ ✅ Allowed
|
|
1333
|
+
* const z: A = Promise.resolve(123);
|
|
1334
|
+
* // ➔ ✅ Allowed
|
|
1335
|
+
*
|
|
1336
|
+
* // ❌ Not allowed (plain object):
|
|
1337
|
+
* // const bad: A = { foo: "bar" };
|
|
1338
|
+
* ```
|
|
1339
|
+
*/
|
|
1340
|
+
type NonPlainObject = BoxedPrimitivesTypes | AnyFunction | Promise<any> | Array<any> | AnObjectNonArray;
|
|
1341
|
+
/** --------------------------------------------------
|
|
1342
|
+
* * ***Utility Type: `AnObjectNonArray`.***
|
|
1343
|
+
* --------------------------------------------------
|
|
1344
|
+
* **Represents all **non-null, non-array, object-like values** in JavaScript/Node.js.**
|
|
1345
|
+
* - ✅ ***Includes:***
|
|
1346
|
+
* - **Built-in objects:** `Date`, `RegExp`, `Error`, `ArrayBuffer`, `DataView`.
|
|
1347
|
+
* - **Collections:** `Map`, `Set`, `WeakMap`, `WeakSet`.
|
|
1348
|
+
* - **Typed arrays:**
|
|
1349
|
+
* `Int8Array`, `Uint8Array`, `Uint8ClampedArray`,
|
|
1350
|
+
* `Int16Array`, `Uint16Array`,
|
|
1351
|
+
* `Int32Array`, `Uint32Array`,
|
|
1352
|
+
* `Float32Array`, `Float64Array`,
|
|
1353
|
+
* `BigInt64Array`, `BigUint64Array`.
|
|
1354
|
+
* - **Browser Web APIs:**
|
|
1355
|
+
* `URL`, `URLSearchParams`, `FormData`, `Headers`, `Response`, `Request`,
|
|
1356
|
+
* `ReadableStream`, `WritableStream`, `TransformStream`,
|
|
1357
|
+
* `MessageChannel`, `MessagePort`, `MessageEvent`,
|
|
1358
|
+
* `Event`, `CustomEvent`, `HTMLElement`, `Node`, `Document`, `Window`,
|
|
1359
|
+
* `CanvasRenderingContext2D`,
|
|
1360
|
+
* `AbortController`, `AbortSignal`,
|
|
1361
|
+
* `TextEncoder`, `TextDecoder`,
|
|
1362
|
+
* `CryptoKey`, `File`, `FileList`, `ImageBitmap`, `WebSocket`.
|
|
1363
|
+
* - **ECMAScript Internationalization API objects:**
|
|
1364
|
+
* `Intl.Collator`, `Intl.DateTimeFormat`, `Intl.NumberFormat`,
|
|
1365
|
+
* `Intl.RelativeTimeFormat`, `Intl.PluralRules`,
|
|
1366
|
+
* `Intl.ListFormat`, `Intl.Locale`.
|
|
1367
|
+
* - **Node.js built-ins:** `Buffer`.
|
|
1368
|
+
* - **Symbols**.
|
|
1369
|
+
* - **Proxies** (wrapping any object).
|
|
1370
|
+
* - The global **`Reflect`** object.
|
|
1371
|
+
* - ❌ ***Excludes:***
|
|
1372
|
+
* - `null`.
|
|
1373
|
+
* - Arrays (`[]`, `new Array()`).
|
|
1374
|
+
* - ℹ️ ***Note:***
|
|
1375
|
+
* - Use this type when you need to represent **any object-like value except arrays and `null`**.
|
|
1376
|
+
* @example
|
|
1377
|
+
* ```ts
|
|
1378
|
+
* const a: AnObjectNonArray = new Date();
|
|
1379
|
+
* const b: AnObjectNonArray = new Map();
|
|
1380
|
+
* const c: AnObjectNonArray = Symbol("id");
|
|
1381
|
+
*
|
|
1382
|
+
* // ❌ These are NOT allowed:
|
|
1383
|
+
* // const x: AnObjectNonArray = null;
|
|
1384
|
+
* // const y: AnObjectNonArray = [];
|
|
1385
|
+
* ```
|
|
1386
|
+
*/
|
|
1387
|
+
type AnObjectNonArray = Date | RegExp | Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> | Error | ArrayBuffer | DataView | TypedArray | WebApiObjects | IntlObjects | NodeBuiltins | symbol | {
|
|
1388
|
+
[Symbol.toStringTag]: "Proxy";
|
|
1389
|
+
} | typeof Reflect;
|
|
1390
|
+
/** -------------------------------------------------------
|
|
1391
|
+
* * ***Utility Type: `IsGeneralArray`.***
|
|
1392
|
+
* -------------------------------------------------------
|
|
1393
|
+
* **Checks if `T` is a **general array type** (`X[]` or `ReadonlyArray<X>`)
|
|
1394
|
+
* instead of a tuple literal.**
|
|
1395
|
+
* - **Behavior:**
|
|
1396
|
+
* - Returns `true` for `string[]`, `(number | boolean)[]`, `any[]`, etc.
|
|
1397
|
+
* - Returns `false` for tuples like `[]`, `[1, 2, 3]`, or `[string, number]`.
|
|
1398
|
+
* @template T - The type to check.
|
|
1399
|
+
* @example
|
|
1400
|
+
* ```ts
|
|
1401
|
+
* type A = IsGeneralArray<string[]>; // ➔ true
|
|
1402
|
+
* type B = IsGeneralArray<[]>; // ➔ false
|
|
1403
|
+
* type C = IsGeneralArray<[1, 2, 3]>; // ➔ false
|
|
1404
|
+
* type D = IsGeneralArray<ReadonlyArray<number>>; // ➔ true
|
|
1405
|
+
* ```
|
|
1406
|
+
*/
|
|
1407
|
+
/** --------------------------------------------------
|
|
1408
|
+
* * ***Utility Type: `ExtractStrict`.***
|
|
1409
|
+
* --------------------------------------------------
|
|
1410
|
+
* **Performs a stricter version of the built-in `Extract<T, U>`
|
|
1411
|
+
* with improved type narrowing.**
|
|
1412
|
+
* - ✅ Especially useful in generic utilities where the
|
|
1413
|
+
* standard `Extract` can widen or collapse unions.
|
|
1414
|
+
* @template T - The full union or set of types.
|
|
1415
|
+
* @template U - The type(s) to be kept from `T`.
|
|
1416
|
+
* @example
|
|
1417
|
+
* ```ts
|
|
1418
|
+
* type A = 'a' | 'b' | 'c';
|
|
1419
|
+
* type B = ExtractStrict<A, 'b' | 'c'>;
|
|
1420
|
+
* // ➔ 'b' | 'c'
|
|
1421
|
+
* ```
|
|
1422
|
+
*/
|
|
1423
|
+
type ExtractStrict<T, U extends T> = T extends unknown ? 0 extends (U extends T ? ([T] extends [U] ? 0 : never) : never) ? T : never : never;
|
|
1424
|
+
/** -------------------------------------------------------
|
|
1425
|
+
* * ***Utility Type: `IsArrayOrTuple`.***
|
|
1426
|
+
* -------------------------------------------------------
|
|
1427
|
+
* **Checks if a given type `T` is an array or tuple type.**
|
|
1428
|
+
* - This includes both mutable (`T[]`) and readonly (`readonly T[]`) arrays.
|
|
1429
|
+
* @template T - The type to check.
|
|
1430
|
+
* @example
|
|
1431
|
+
* type A = IsArrayOrTuple<string[]>;
|
|
1432
|
+
* // ➔ true
|
|
1433
|
+
* type B = IsArrayOrTuple<readonly [string, number]>;
|
|
1434
|
+
* // ➔ true
|
|
1435
|
+
* type C = IsArrayOrTuple<string>; // ➔ false
|
|
1436
|
+
*/
|
|
1437
|
+
type IsArrayOrTuple<T> = T extends readonly any[] ? true : false;
|
|
1438
|
+
/** -------------------------------------------------------
|
|
1439
|
+
* * ***Utility Type: `IsConstructor`.***
|
|
1440
|
+
* -------------------------------------------------------
|
|
1441
|
+
* **Checks whether a given type `T` is a constructor type.**
|
|
1442
|
+
*
|
|
1443
|
+
* This utility evaluates to `true` if `T` has a constructor
|
|
1444
|
+
* signature, including constructors of **abstract classes**.
|
|
1445
|
+
*
|
|
1446
|
+
* It uses the `abstract new (...args) => instance` signature,
|
|
1447
|
+
* meaning it matches any type that represents a constructor —
|
|
1448
|
+
* even if the class cannot be instantiated directly.
|
|
1449
|
+
*
|
|
1450
|
+
* - **Behavior:**
|
|
1451
|
+
* - Evaluates to `true` if `T` has a compatible constructor signature.
|
|
1452
|
+
* - Optionally validates the **constructor parameter tuple**
|
|
1453
|
+
* and **instance type** using the generic parameters `A` and `R`.
|
|
1454
|
+
*
|
|
1455
|
+
* - **Difference from {@link IsNewable | `IsNewable`}:**
|
|
1456
|
+
* - `IsConstructor` returns `true` for **both concrete and abstract constructors**.
|
|
1457
|
+
* - `IsNewable` only returns `true` for constructors that can be
|
|
1458
|
+
* instantiated with `new`.
|
|
1459
|
+
*
|
|
1460
|
+
* In other words:
|
|
1461
|
+
*
|
|
1462
|
+
* ```ts
|
|
1463
|
+
* IsConstructor ⊇ IsNewable
|
|
1464
|
+
* ```
|
|
1465
|
+
*
|
|
1466
|
+
* @template T - The type to check.
|
|
1467
|
+
* @template A - Expected constructor parameter tuple (default: `any[]`).
|
|
1468
|
+
* @template R - Expected instance type (default: `any`).
|
|
1469
|
+
*
|
|
1470
|
+
* @example
|
|
1471
|
+
* ```ts
|
|
1472
|
+
* class A {}
|
|
1473
|
+
* abstract class B {}
|
|
1474
|
+
*
|
|
1475
|
+
* type T1 = IsConstructor<typeof A>;
|
|
1476
|
+
* // ➔ true
|
|
1477
|
+
* type T2 = IsConstructor<typeof B>;
|
|
1478
|
+
* // ➔ true
|
|
1479
|
+
* ```
|
|
1480
|
+
*
|
|
1481
|
+
* @example
|
|
1482
|
+
* ```ts
|
|
1483
|
+
* class User {
|
|
1484
|
+
* constructor(x: number, y: string) {}
|
|
1485
|
+
* }
|
|
1486
|
+
*
|
|
1487
|
+
* type T1 = IsConstructor<typeof User, [number, string], User>;
|
|
1488
|
+
* // ➔ true
|
|
1489
|
+
* type T2 = IsConstructor<typeof User, [string], User>;
|
|
1490
|
+
* // ➔ false
|
|
1491
|
+
* ```
|
|
1492
|
+
*
|
|
1493
|
+
* @example
|
|
1494
|
+
* ```ts
|
|
1495
|
+
* type T1 = IsConstructor<() => void>;
|
|
1496
|
+
* // ➔ false
|
|
1497
|
+
* ```
|
|
1498
|
+
*/
|
|
1499
|
+
type IsConstructor<T, A extends any[] = any[], R = any> = T extends (abstract new (...args: A) => R) ? true : false;
|
|
1500
|
+
/** -------------------------------------------------------
|
|
1501
|
+
* * ***Utility Type: `IsFunction`.***
|
|
1502
|
+
* -------------------------------------------------------
|
|
1503
|
+
* **Checks if a given type `T` is a callable function type.**
|
|
1504
|
+
* @template T - The type to check.
|
|
1505
|
+
* @example
|
|
1506
|
+
* type A = IsFunction<() => void>; // ➔ true
|
|
1507
|
+
* type B = IsFunction<string>; // ➔ false
|
|
1508
|
+
*/
|
|
1509
|
+
type IsFunction<T> = T extends AnyFunction ? true : false;
|
|
1510
|
+
/** -------------------------------------------------------
|
|
1511
|
+
* * ***Utility Type: `Primitive`.***
|
|
1512
|
+
* -------------------------------------------------------
|
|
1513
|
+
* **Represents **all primitive types in JavaScript/TypeScript**,
|
|
1514
|
+
* including their literal variants.**
|
|
1515
|
+
* - **This type matches:**
|
|
1516
|
+
* - Core primitive types:
|
|
1517
|
+
* - `string`, `number`, `boolean`, `bigint`, `symbol`, `null`, `undefined`.
|
|
1518
|
+
* - Literal counterparts:
|
|
1519
|
+
* - `"foo"`, `42`, `true`, etc.
|
|
1520
|
+
* - ⚠️ ***Note:***
|
|
1521
|
+
* - Unlike some definitions, this does **not** include `void` or `never`,
|
|
1522
|
+
* since they are TypeScript-specific keywords, not runtime primitives.
|
|
1523
|
+
* @example
|
|
1524
|
+
* ```ts
|
|
1525
|
+
* type A = Primitive;
|
|
1526
|
+
* // ➔ any strict primitive type
|
|
1527
|
+
* type B = "hello" extends Primitive ? true : false;
|
|
1528
|
+
* // ➔ true
|
|
1529
|
+
* type C = void extends Primitive ? true : false;
|
|
1530
|
+
* // ➔ false
|
|
1531
|
+
* ```
|
|
1532
|
+
*/
|
|
1533
|
+
type Primitive = string | number | bigint | boolean | symbol | null | undefined;
|
|
1534
|
+
/** -------------------------------------------------------
|
|
1535
|
+
* * ***Utility Type: `IsPrimitive`.***
|
|
1536
|
+
* -------------------------------------------------------
|
|
1537
|
+
* **Checks if a given type `T` is a **strict primitive type** in JavaScript/TypeScript,
|
|
1538
|
+
* including literal variants.**
|
|
1539
|
+
* - **Behavior:**
|
|
1540
|
+
* - ***Includes:***
|
|
1541
|
+
* - `string`, `number`, `bigint`, `boolean`, `symbol`, `null`, `undefined`.
|
|
1542
|
+
* - Literal types like: `"foo"`, `42`, `true`.
|
|
1543
|
+
* - ***Excludes:***
|
|
1544
|
+
* - `void` (absence of value).
|
|
1545
|
+
* - `never` (impossible type).
|
|
1546
|
+
* - `object`, `unknown`, `Date`, `arrays`, `functions`, etc.
|
|
1547
|
+
* @template T - The type to check
|
|
1548
|
+
* @example
|
|
1549
|
+
* ```ts
|
|
1550
|
+
* type A = IsPrimitive<"foo">; // ➔ true
|
|
1551
|
+
* type B = IsPrimitive<null>; // ➔ true
|
|
1552
|
+
* type C = IsPrimitive<number>; // ➔ true
|
|
1553
|
+
* type D = IsPrimitive<undefined>; // ➔ true
|
|
1554
|
+
* type E = IsPrimitive<{}>; // ➔ false
|
|
1555
|
+
* type F = IsPrimitive<void>; // ➔ false
|
|
1556
|
+
* type G = IsPrimitive<never>; // ➔ false
|
|
1557
|
+
* type H = IsPrimitive<unknown>; // ➔ false
|
|
1558
|
+
* type I = IsPrimitive<object>; // ➔ false
|
|
1559
|
+
* type J = IsPrimitive<Date>; // ➔ false
|
|
1560
|
+
* type K = IsPrimitive<[]>; // ➔ false
|
|
1561
|
+
* type L = IsPrimitive<() => void>; // ➔ false
|
|
1562
|
+
* ```
|
|
1563
|
+
*/
|
|
1564
|
+
type IsPrimitive<T> = IsNever<T> extends true ? false : T extends Primitive ? true : false;
|
|
1565
|
+
/** -------------------------------------------------------
|
|
1566
|
+
* * ***Utility Type: `IsRealPrimitive`.***
|
|
1567
|
+
* -------------------------------------------------------
|
|
1568
|
+
* **Checks if a given type `T` is a **real primitive type** in JavaScript/TypeScript,
|
|
1569
|
+
* based on runtime behavior, **excluding `null`** but including `undefined`.**
|
|
1570
|
+
* - **Behavior:**
|
|
1571
|
+
* - ***Includes:***
|
|
1572
|
+
* - `string`, `number`, `bigint`, `boolean`, `symbol`, `undefined`.
|
|
1573
|
+
* - Literal types like: `"foo"`, `42`, `true`.
|
|
1574
|
+
* - ***Excludes:***
|
|
1575
|
+
* - `null`.
|
|
1576
|
+
* - `never` (impossible type).
|
|
1577
|
+
* - Objects, arrays, functions, `Date`, `unknown`, etc.
|
|
1578
|
+
* - ⚠️ ***Note:***
|
|
1579
|
+
* - This aligns with runtime `typeof` checks in JS:
|
|
1580
|
+
* - `typeof null === "object"`,
|
|
1581
|
+
* so `null` is excluded from **“real primitives”**.
|
|
1582
|
+
* @template T - The type to check.
|
|
1583
|
+
* @example
|
|
1584
|
+
* ```ts
|
|
1585
|
+
* type A = IsRealPrimitive<42>; // ➔ true
|
|
1586
|
+
* type B = IsRealPrimitive<string>; // ➔ true
|
|
1587
|
+
* type C = IsRealPrimitive<boolean>; // ➔ true
|
|
1588
|
+
* type D = IsRealPrimitive<undefined>; // ➔ true
|
|
1589
|
+
* type E = IsRealPrimitive<{}>; // ➔ false
|
|
1590
|
+
* type F = IsRealPrimitive<[]>; // ➔ false
|
|
1591
|
+
* type G = IsRealPrimitive<null>; // ➔ false
|
|
1592
|
+
* type H = IsRealPrimitive<Date>; // ➔ false
|
|
1593
|
+
* type I = IsRealPrimitive<() => void>; // ➔ false
|
|
1594
|
+
* ```
|
|
1595
|
+
*/
|
|
1596
|
+
/** * Applies readonly behavior according to mode.
|
|
1597
|
+
*
|
|
1598
|
+
*/
|
|
1599
|
+
type ApplyReadonlyMode<T, Mode extends PrettifyOptions["readonlyMode"]> = Mode extends "remove" ? { -readonly [K in keyof T]: T[K] } : Mode extends "preserve" ? { readonly [K in keyof T]: T[K] } : { [K in keyof T]: T[K] };
|
|
1600
|
+
/** ---------------------------------------------------------------------------
|
|
1601
|
+
* * ***Options for {@link Prettify|`Prettify`}.***
|
|
1602
|
+
* ---------------------------------------------------------------------------
|
|
1603
|
+
* **Options for customizing the behavior of the {@link Prettify | **`Prettify`**} type utility.**
|
|
1604
|
+
*/
|
|
1605
|
+
type PrettifyOptions = {
|
|
1606
|
+
/** -------------------------------------------------------
|
|
1607
|
+
* * ***recursive***
|
|
1608
|
+
* -------------------------------------------------------
|
|
1609
|
+
* **Enables **deep prettification** of types when set to `true`.**
|
|
1610
|
+
* @description
|
|
1611
|
+
* By default (`false`), {@link Prettify | **`Prettify`**} only flattens the **top-level shape**
|
|
1612
|
+
* of objects and intersections. Nested objects, arrays, and tuples remain as-is
|
|
1613
|
+
* unless this option is enabled.
|
|
1614
|
+
* - ***Behavior when `true`:***
|
|
1615
|
+
* - **Plain objects**: Nested intersections are expanded recursively.
|
|
1616
|
+
* - **Arrays & tuples**: Each element type is recursively prettified.
|
|
1617
|
+
* - **Readonly handling**: Nested properties respect the `readonlyMode` option.
|
|
1618
|
+
* - **Functions, constructors, and built-in objects** (Set, Map, Date, Promise, etc.)
|
|
1619
|
+
* are **not** affected or expanded.
|
|
1620
|
+
* - **Nested intersections**: Combined properties are flattened recursively.
|
|
1621
|
+
* - ⚠️ ***Notes:***
|
|
1622
|
+
* - Recursive mode only applies to **plain objects**, **arrays**, and **tuples**.
|
|
1623
|
+
* - Readonly modifiers on nested properties follow the `readonlyMode` rules:
|
|
1624
|
+
* - `"auto"` ➔ keep as-is
|
|
1625
|
+
* - `"remove"` ➔ strip readonly
|
|
1626
|
+
* - `"preserve"` ➔ make readonly
|
|
1627
|
+
* - Arrays and tuples maintain `readonly` if the original type is `readonly` and `readonlyMode` is `"auto"` or `"preserve"`.
|
|
1628
|
+
* @default false
|
|
1629
|
+
* @example
|
|
1630
|
+
* ```ts
|
|
1631
|
+
* type Nested = {
|
|
1632
|
+
* a: {
|
|
1633
|
+
* readonly b: { c: number } & { d: string }
|
|
1634
|
+
* } & { e: boolean };
|
|
1635
|
+
* list: readonly ({ id: number } & { name: string })[];
|
|
1636
|
+
* set: Set<{ x: number } & { y: string }>;
|
|
1637
|
+
* };
|
|
1638
|
+
*
|
|
1639
|
+
* // Top-level only (default)
|
|
1640
|
+
* type Shallow = Prettify<Nested>;
|
|
1641
|
+
* // ➔ {
|
|
1642
|
+
* // a: { readonly b: { c: number } & { d: string } } & { e: boolean };
|
|
1643
|
+
* // list: readonly ({ id: number } & { name: string })[];
|
|
1644
|
+
* // set: Set<{ x: number } & { y: string }>;
|
|
1645
|
+
* // }
|
|
1646
|
+
*
|
|
1647
|
+
* // Fully recursive flatten
|
|
1648
|
+
* type Deep = Prettify<Nested, { recursive: true }>;
|
|
1649
|
+
* // ➔ {
|
|
1650
|
+
* // a: { readonly b: { c: number; d: string }; e: boolean };
|
|
1651
|
+
* // list: readonly { id: number; name: string }[];
|
|
1652
|
+
* // set: Set<{ x: number } & { y: string }>; // built-in ignored
|
|
1653
|
+
* // }
|
|
1654
|
+
* ```
|
|
1655
|
+
*/
|
|
1656
|
+
recursive?: boolean;
|
|
1657
|
+
/** -------------------------------------------------------
|
|
1658
|
+
* * ***readonlyMode***
|
|
1659
|
+
* -------------------------------------------------------
|
|
1660
|
+
* **Determines how `readonly` modifiers are applied to properties
|
|
1661
|
+
* when using {@link Prettify}.**
|
|
1662
|
+
* - **Modes:**
|
|
1663
|
+
* - `"auto"` ➔ Keep `readonly` exactly as in the original type (default).
|
|
1664
|
+
* - `"remove"` ➔ Remove all `readonly` modifiers.
|
|
1665
|
+
* - `"preserve"` ➔ Make all properties `readonly`.
|
|
1666
|
+
* - **Behavior:**
|
|
1667
|
+
* - Applies to both **top-level** and **nested properties** (if `recursive` is `true`).
|
|
1668
|
+
* - Arrays and tuples preserve or adjust `readonly` according to the selected mode:
|
|
1669
|
+
* - `"auto"` ➔ preserve array/tuple readonly as-is.
|
|
1670
|
+
* - `"remove"` ➔ array/tuple becomes mutable.
|
|
1671
|
+
* - `"preserve"` ➔ array/tuple becomes readonly.
|
|
1672
|
+
* - Functions, constructors, and built-in objects (Set, Map, Date, Promise, etc.) are **not affected**.
|
|
1673
|
+
* - Nested intersections respect `readonlyMode` recursively if `recursive` is enabled.
|
|
1674
|
+
* - ⚠️ ***Notes:***
|
|
1675
|
+
* - For nested objects, `readonly` behavior only changes if `recursive: true`.
|
|
1676
|
+
* - `readonlyMode` does **not** override `readonly` on function parameters, methods, or constructors.
|
|
1677
|
+
* @default "auto"
|
|
1678
|
+
* @example
|
|
1679
|
+
* ```ts
|
|
1680
|
+
* type T = { readonly a: number; b: string };
|
|
1681
|
+
*
|
|
1682
|
+
* // Default: auto
|
|
1683
|
+
* type Auto = Prettify<T, { readonlyMode: "auto" }>;
|
|
1684
|
+
* // ➔ { readonly a: number; b: string }
|
|
1685
|
+
*
|
|
1686
|
+
* // Remove readonly
|
|
1687
|
+
* type Remove = Prettify<T, { readonlyMode: "remove" }>;
|
|
1688
|
+
* // ➔ { a: number; b: string }
|
|
1689
|
+
*
|
|
1690
|
+
* // Force all readonly
|
|
1691
|
+
* type Preserve = Prettify<T, { readonlyMode: "preserve" }>;
|
|
1692
|
+
* // ➔ { readonly a: number; readonly b: string }
|
|
1693
|
+
*
|
|
1694
|
+
* // Recursive + preserve
|
|
1695
|
+
* type Nested = {
|
|
1696
|
+
* config: { readonly port: number } & { host: string }
|
|
1697
|
+
* };
|
|
1698
|
+
* type RecursivePreserve = Prettify<Nested, { recursive: true; readonlyMode: "preserve" }>;
|
|
1699
|
+
* // ➔ { readonly config: { readonly port: number; readonly host: string } }
|
|
1700
|
+
* ```
|
|
1701
|
+
*/
|
|
1702
|
+
readonlyMode?: Extract<"auto" | "remove" | "preserve", string>;
|
|
1703
|
+
/** ---------------------------------
|
|
1704
|
+
* * ***Skips applying the prettify transformation.***
|
|
1705
|
+
* ---------------------------------
|
|
1706
|
+
*
|
|
1707
|
+
* When enabled, the output will be returned as-is without running the
|
|
1708
|
+
* prettify step.
|
|
1709
|
+
*
|
|
1710
|
+
* @default false
|
|
1711
|
+
*
|
|
1712
|
+
*/
|
|
1713
|
+
skipPrettify?: boolean;
|
|
1714
|
+
};
|
|
1715
|
+
/** -------------------------------------------------------
|
|
1716
|
+
* * ***DefaultPrettifyOptions***
|
|
1717
|
+
* -------------------------------------------------------
|
|
1718
|
+
* **Default options {@link Prettify | **`Prettify`**} used when no custom options are provided.**
|
|
1719
|
+
*/
|
|
1720
|
+
type DefaultPrettifyOptions = {
|
|
1721
|
+
skipPrettify: false;
|
|
1722
|
+
recursive: false;
|
|
1723
|
+
readonlyMode: "auto";
|
|
1724
|
+
};
|
|
1725
|
+
type MergeReadonlyIntersection<T> = T extends readonly any[] ? T : T extends object ? { [K in keyof T]: T[K] } : T;
|
|
1726
|
+
/** -------------------------------------------------------
|
|
1727
|
+
* * ***Utility Type: `Prettify`.***
|
|
1728
|
+
* -------------------------------------------------------
|
|
1729
|
+
* **Flattens and simplifies complex TypeScript types into a more
|
|
1730
|
+
* human-readable form, by forcing the compiler to expand intersections.**
|
|
1731
|
+
* @description
|
|
1732
|
+
* By default, only the **top-level shape** of an object is flattened.
|
|
1733
|
+
* To also prettify **nested objects**, set the `recursive` option.
|
|
1734
|
+
* - ⚠️ ***Note:***
|
|
1735
|
+
* - `recursive: true` only affects **plain objects** and **arrays/tuples**.
|
|
1736
|
+
* - Built-in objects like `Set`, `Map`, `Date`, `Promise`, etc.
|
|
1737
|
+
* will **not** be recursively prettified.
|
|
1738
|
+
* - `readonly` handling is controlled via the `readonlyMode` option.
|
|
1739
|
+
* - **ℹ️ Options:**
|
|
1740
|
+
* - `recursive?: boolean` (default: `false`):
|
|
1741
|
+
* - Whether to recursively expand nested objects and intersections.
|
|
1742
|
+
* - `readonlyMode?: "auto" | "remove" | "preserve"` (default: `"auto"`):
|
|
1743
|
+
* - How `readonly` modifiers are treated:
|
|
1744
|
+
* - `"auto"` ➔ preserve `readonly` as-is (**default**).
|
|
1745
|
+
* - `"remove"` ➔ strip all `readonly`.
|
|
1746
|
+
* - `"preserve"` ➔ enforce `readonly` everywhere.
|
|
1747
|
+
* @template T - The type to prettify.
|
|
1748
|
+
* @template Options - Configuration options.
|
|
1749
|
+
* @example
|
|
1750
|
+
* ```ts
|
|
1751
|
+
* // --- Top-level only (default) ---
|
|
1752
|
+
* type T0 = Prettify<{ a: number } & { b: string }>;
|
|
1753
|
+
* // ➔ { a: number; b: string }
|
|
1754
|
+
*
|
|
1755
|
+
* // --- Recursive expansion of nested objects ---
|
|
1756
|
+
* type T1 = Prettify<
|
|
1757
|
+
* { a: { x: number } & { y: string } } & { b: boolean },
|
|
1758
|
+
* { recursive: true }
|
|
1759
|
+
* >;
|
|
1760
|
+
* // ➔ { a: { x: number; y: string }; b: boolean }
|
|
1761
|
+
*
|
|
1762
|
+
* // --- Readonly handling modes ---
|
|
1763
|
+
* type T2 = { readonly id: number; name: string };
|
|
1764
|
+
*
|
|
1765
|
+
* type R1 = Prettify<T2>;
|
|
1766
|
+
* // (default: readonlyMode = "auto")
|
|
1767
|
+
* // ➔ { readonly id: number; name: string }
|
|
1768
|
+
*
|
|
1769
|
+
* type R2 = Prettify<T2, { readonlyMode: "remove" }>;
|
|
1770
|
+
* // ➔ { id: number; name: string }
|
|
1771
|
+
*
|
|
1772
|
+
* type R3 = Prettify<T2, { readonlyMode: "preserve" }>;
|
|
1773
|
+
* // ➔ { readonly id: number; readonly name: string }
|
|
1774
|
+
*
|
|
1775
|
+
* // --- Readonly + mutable intersection ---
|
|
1776
|
+
* type T3 = Prettify<{ readonly a: number } & { a: number; b: boolean }>;
|
|
1777
|
+
* // ➔ { a: number; b: boolean }
|
|
1778
|
+
* // (in "auto" mode, readonly lose over mutable)
|
|
1779
|
+
*
|
|
1780
|
+
* // --- Nested readonly with recursive ---
|
|
1781
|
+
* type T4 = Prettify<
|
|
1782
|
+
* { config: { readonly port: number } & { host: string } },
|
|
1783
|
+
* { recursive: true }
|
|
1784
|
+
* >;
|
|
1785
|
+
* // ➔ { config: { readonly port: number; host: string } }
|
|
1786
|
+
*
|
|
1787
|
+
* // --- Arrays with readonly ---
|
|
1788
|
+
* type T5 = Prettify<
|
|
1789
|
+
* { list: readonly ({ id: number } & { name: string })[] },
|
|
1790
|
+
* { recursive: true }
|
|
1791
|
+
* >;
|
|
1792
|
+
* // (readonly on array is preserved in "auto" mode)
|
|
1793
|
+
* // ➔ { list: readonly { id: number; name: string }[] }
|
|
1794
|
+
*
|
|
1795
|
+
* type T6 = Prettify<
|
|
1796
|
+
* { list: readonly ({ id: number } & { name: string })[] },
|
|
1797
|
+
* { recursive: true; readonlyMode: "remove" }
|
|
1798
|
+
* >;
|
|
1799
|
+
* // ➔ { list: { id: number; name: string }[] }
|
|
1800
|
+
*
|
|
1801
|
+
* // --- Built-in objects are ignored (not expanded) ---
|
|
1802
|
+
* type T7 = Prettify<
|
|
1803
|
+
* { s: Set<{ a: number } & { b: string }> },
|
|
1804
|
+
* { recursive: true }
|
|
1805
|
+
* >;
|
|
1806
|
+
* // ➔ { s: Set<{ a: number } & { b: string }> }
|
|
1807
|
+
* ```
|
|
1808
|
+
*/
|
|
1809
|
+
type Prettify<T, Options extends PrettifyOptions = DefaultPrettifyOptions> = Options["skipPrettify"] extends true ? T : IsPrimitive<T> extends true ? T : IsFunction<T> extends true ? T : IsConstructor<T> extends true ? T : IsArrayOrTuple<T> extends true ? ApplyReadonlyMode<{ [K in keyof T]: If<Options["recursive"], Prettify<T[K], Options>, T[K]> }, Options["readonlyMode"]> : T extends NonPlainObject ? T : T extends object ? ApplyReadonlyMode<MergeReadonlyIntersection<{ [K in keyof T]: If<Options["recursive"], Prettify<T[K], Options>, T[K]> }>, Options["readonlyMode"]> : T;
|
|
1810
|
+
/** ---------------------------------------------------------------------------
|
|
1811
|
+
* * ***Options for {@link Mutable | `Mutable`}.***
|
|
1812
|
+
* ---------------------------------------------------------------------------
|
|
1813
|
+
* **Configuration options for the ***{@link Mutable | **`Mutable`**}*** type utilities.**
|
|
1814
|
+
* @example
|
|
1815
|
+
* ```ts
|
|
1816
|
+
* type Opt1 = MutableOptions;
|
|
1817
|
+
* // ➔ { recursive: boolean }
|
|
1818
|
+
* ```
|
|
1819
|
+
*/
|
|
1820
|
+
/** -------------------------------------------------------
|
|
1821
|
+
* * ***Utility Type: `IsArray`.***
|
|
1822
|
+
* -------------------------------------------------------
|
|
1823
|
+
* **Returns a boolean whether the passed argument is an array.**
|
|
1824
|
+
* @example
|
|
1825
|
+
* type Case1 = IsArray<[]>;
|
|
1826
|
+
* // ➔ true
|
|
1827
|
+
* type Case2 = IsArray<string>;
|
|
1828
|
+
* // ➔ false
|
|
1829
|
+
*/
|
|
1830
|
+
type IsArray<T> = AndArr<[Not<IsAny<T>>, Not<IsNever<T>>, Extends<T, readonly unknown[]>]>;
|
|
1831
|
+
/** -------------------------------------------------------
|
|
1832
|
+
* * ***Utility Type: `IsMutableArray`.***
|
|
1833
|
+
* -------------------------------------------------------
|
|
1834
|
+
* **Returns a boolean whether the passed argument is a mutable array.**
|
|
1835
|
+
* @example
|
|
1836
|
+
* type Case1 = IsMutableArray<[]>;
|
|
1837
|
+
* // ➔ true
|
|
1838
|
+
* type Case2 = IsMutableArray<readonly []>;
|
|
1839
|
+
* // ➔ false
|
|
1840
|
+
*/
|
|
1841
|
+
/** --------------------------------------------------
|
|
1842
|
+
* * ***Utility Type: `Nullish`.***
|
|
1843
|
+
* --------------------------------------------------
|
|
1844
|
+
* **Useful as a shorthand when working with optional or missing values.**
|
|
1845
|
+
* - **Represents all values considered **`nullish`**:**
|
|
1846
|
+
* - `null`
|
|
1847
|
+
* - `undefined`
|
|
1848
|
+
*/
|
|
1849
|
+
type Nullish = null | undefined;
|
|
1850
|
+
/** --------------------------------------------------
|
|
1851
|
+
* * ***Utility Type: `Nullable`.***
|
|
1852
|
+
* --------------------------------------------------
|
|
1853
|
+
* **Represents a type that can be either `T` or `null`.**
|
|
1854
|
+
* @template T - The base type.
|
|
1855
|
+
* @example
|
|
1856
|
+
* ```ts
|
|
1857
|
+
* type A = Nullable<string>; // ➔ string | null
|
|
1858
|
+
* ```
|
|
1859
|
+
*/
|
|
1860
|
+
/** --------------------------------------------------
|
|
1861
|
+
* * ***Utility Type: `Nilable`.***
|
|
1862
|
+
* --------------------------------------------------
|
|
1863
|
+
* **Represents a type that can be either `T`, `null`, or `undefined`.**
|
|
1864
|
+
* @template T - The base type.
|
|
1865
|
+
* @example
|
|
1866
|
+
* ```ts
|
|
1867
|
+
* type A = Nilable<number>; // ➔ number | null | undefined
|
|
1868
|
+
* ```
|
|
1869
|
+
*/
|
|
1870
|
+
type Nilable<T> = T | null | undefined;
|
|
1871
|
+
/** --------------------------------------------------
|
|
1872
|
+
* * ***Utility Type: `Undefinedable`.***
|
|
1873
|
+
* --------------------------------------------------
|
|
1874
|
+
* **Represents a type that can be either `T` or `undefined`.**
|
|
1875
|
+
* @template T - The base type.
|
|
1876
|
+
* @example
|
|
1877
|
+
* ```ts
|
|
1878
|
+
* type A = Undefinedable<boolean>; // ➔ boolean | undefined
|
|
1879
|
+
* ```
|
|
1880
|
+
*/
|
|
1881
|
+
/** --------------------------------------------------
|
|
1882
|
+
* * ***Utility Type: `KeepNull`.***
|
|
1883
|
+
* --------------------------------------------------
|
|
1884
|
+
* **Keeps `null` in the output type **only if** the input type `T` includes `null`, otherwise resolves to `never`.**
|
|
1885
|
+
* @template T - Input type to check for `null`.
|
|
1886
|
+
* @example
|
|
1887
|
+
* ```ts
|
|
1888
|
+
* type A = KeepNull<string | null>; // ➔ null
|
|
1889
|
+
* type B = KeepNull<string>; // ➔ never
|
|
1890
|
+
* ```
|
|
1891
|
+
*/
|
|
1892
|
+
type KeepNull<T> = null extends T ? null : never;
|
|
1893
|
+
/** --------------------------------------------------
|
|
1894
|
+
* * ***Utility Type: `KeepUndef`.***
|
|
1895
|
+
* --------------------------------------------------
|
|
1896
|
+
* **Keeps `undefined` in the output type **only if** the input type `T` includes `undefined`, otherwise resolves to `never`.**
|
|
1897
|
+
* @template T - Input type to check for `undefined`.
|
|
1898
|
+
* @example
|
|
1899
|
+
* ```ts
|
|
1900
|
+
* type A = KeepUndef<number | undefined>; // ➔ undefined
|
|
1901
|
+
* type B = KeepUndef<number>; // ➔ never
|
|
1902
|
+
* ```
|
|
1903
|
+
*/
|
|
1904
|
+
type KeepUndef<T> = undefined extends T ? undefined : never;
|
|
1905
|
+
/** -------------------------------------------------------
|
|
1906
|
+
* * ***Utility Type: `NullToUndefined`.***
|
|
1907
|
+
* -------------------------------------------------------
|
|
1908
|
+
* **Transforms `null` or `undefined` types into `undefined`, otherwise, returns
|
|
1909
|
+
* the original type `T` unchanged.**
|
|
1910
|
+
* @template T - The input type to transform.
|
|
1911
|
+
* @example
|
|
1912
|
+
* ```ts
|
|
1913
|
+
* type A = NullToUndefined<null>; // ➔ undefined
|
|
1914
|
+
* type B = NullToUndefined<undefined>; // ➔ undefined
|
|
1915
|
+
* type C = NullToUndefined<string>; // ➔ string
|
|
1916
|
+
* type D = NullToUndefined<null[]>; // ➔ null[]
|
|
1917
|
+
* type E = NullToUndefined<(string | null)[]>; // ➔ (string | null)[]
|
|
1918
|
+
* ```
|
|
1919
|
+
*/
|
|
1920
|
+
type NullToUndefined<T> = T extends null ? undefined : T extends undefined ? undefined : T;
|
|
1921
|
+
/** -------------------------------------------------------
|
|
1922
|
+
* * ***Utility Type: `NonNullableObject`.***
|
|
1923
|
+
* -------------------------------------------------------
|
|
1924
|
+
* **Makes all properties of the object type `T` non-nullable.**
|
|
1925
|
+
* @template T - Object type to transform.
|
|
1926
|
+
* @example
|
|
1927
|
+
* ```ts
|
|
1928
|
+
* type A = NonNullableObject<{ a: string | null; b: number | undefined }>;
|
|
1929
|
+
* // ➔ { a: string; b: number }
|
|
1930
|
+
* ```
|
|
1931
|
+
*/
|
|
1932
|
+
/** --------------------------------------------------
|
|
1933
|
+
* * ***Internal Utility Type for: {@link NumberRangeUnion | `NumberRangeUnion`}.***
|
|
1934
|
+
* --------------------------------------------------
|
|
1935
|
+
* @template N - Starting/Ending number of the range (inclusive).
|
|
1936
|
+
* @template Acc - Internal accumulator for recursion (do not set manually).
|
|
1937
|
+
*/
|
|
1938
|
+
type Enumerate<N extends number, Acc extends number[] = []> = Acc["length"] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc["length"]]>;
|
|
1939
|
+
/** --------------------------------------------------
|
|
1940
|
+
* * ***Utility Type: `NumberRangeUnion`.***
|
|
1941
|
+
* --------------------------------------------------
|
|
1942
|
+
* **Generate a union type of numbers from `From` to `To` using enumeration.**
|
|
1943
|
+
* @description
|
|
1944
|
+
* Produces a **numeric union type** from `From` to `To` (inclusive),
|
|
1945
|
+
* using a simpler approach based on `Enumerate<N>` helper type.
|
|
1946
|
+
* - ✅ Straightforward & easy to reason about.
|
|
1947
|
+
* - ⚠️ Still limited by TypeScript recursion depth (safe up to `999`).
|
|
1948
|
+
* - ⚙️ Best used for **smaller ranges** (`≤ 100`) or when readability matters.
|
|
1949
|
+
* - ℹ️ For **larger ranges** (`≥ 101`) use {@link NumberRangeLimit | `NumberRangeLimit`} instead.
|
|
1950
|
+
* @template From - Starting number of the range (inclusive).
|
|
1951
|
+
* @template To - Ending number of the range (inclusive).
|
|
1952
|
+
* @example
|
|
1953
|
+
* ```ts
|
|
1954
|
+
* type RangeA = NumberRangeUnion<3, 6>;
|
|
1955
|
+
* // ➔ 3 | 4 | 5 | 6
|
|
1956
|
+
* type RangeB = NumberRangeUnion<0, 2>;
|
|
1957
|
+
* // ➔ 0 | 1 | 2
|
|
1958
|
+
* type RangeC = NumberRangeUnion<8, 8>;
|
|
1959
|
+
* // ➔ 8
|
|
1960
|
+
* type RangeD = NumberRangeUnion<20, 10>;
|
|
1961
|
+
* // ➔ 10
|
|
1962
|
+
* ```
|
|
1963
|
+
*/
|
|
1964
|
+
type NumberRangeUnion<From extends number, To extends number> = From extends To ? From : Exclude<Enumerate<To>, Enumerate<From>> extends never ? To : Exclude<Enumerate<To>, Enumerate<From>> | To;
|
|
1965
|
+
/** --------------------------------------------------
|
|
1966
|
+
* * ***Internal Utility Type for: {@link NumberRangeLimit | `NumberRangeLimit`}.***
|
|
1967
|
+
* --------------------------------------------------
|
|
1968
|
+
* @template From - Starting number of the range (inclusive).
|
|
1969
|
+
* @template To - Ending number of the range (inclusive).
|
|
1970
|
+
* @template Result - Internal accumulator for recursion (do not set manually).
|
|
1971
|
+
*/
|
|
1972
|
+
/** --------------------------------------------------
|
|
1973
|
+
* * ***Utility Type: `OmitStrict`.***
|
|
1974
|
+
* --------------------------------------------------
|
|
1975
|
+
* **Strictly omits keys `K` from type `T`, with optional flattening for readability using `Prettify`.**
|
|
1976
|
+
* - **Behavior:**
|
|
1977
|
+
* - ✅ Enhances autocomplete and type inspection clarity in editors.
|
|
1978
|
+
* - ✅ Optionally flattens nested intersections or mapped types into a cleaner shape.
|
|
1979
|
+
* @template T - The original object type.
|
|
1980
|
+
* @template K - The keys to omit from `T`.
|
|
1981
|
+
* @template PrettifyOptions - Options controlling whether the resulting
|
|
1982
|
+
* type should be normalized using the `Prettify` helper.
|
|
1983
|
+
* @example
|
|
1984
|
+
* ```ts
|
|
1985
|
+
* type A = { a: number; b: string; c: boolean };
|
|
1986
|
+
* type B = OmitStrict<A, 'b'>;
|
|
1987
|
+
* // ➔ { a: number; c: boolean }
|
|
1988
|
+
*
|
|
1989
|
+
* type C = OmitStrict<A, 'b', { skipPrettify: true }>;
|
|
1990
|
+
* // ➔ Omit without prettifying, keeps intersection structure
|
|
1991
|
+
*
|
|
1992
|
+
* type D = OmitStrict<A, 'b', true, { recursive: false }>;
|
|
1993
|
+
* // ➔ Prettifies only top level, does not recurse into nested objects
|
|
1994
|
+
* ```
|
|
1995
|
+
*/
|
|
1996
|
+
type OmitStrict<T, K extends keyof T, PrettifyOptions$9 extends PrettifyOptions = DefaultPrettifyOptions> = Prettify<Omit<T, K>, PrettifyOptions$9>;
|
|
1997
|
+
/** ----------------------------------------------------------------
|
|
1998
|
+
* * ***Options for {@link OverrideTypes | `OverrideTypes`}.***
|
|
1999
|
+
* ----------------------------------------------------------------
|
|
2000
|
+
* Configuration options controlling how overriding behaves.
|
|
2001
|
+
*/
|
|
2002
|
+
type OverrideTypesOptions = {
|
|
2003
|
+
/** * ***Whether overriding keys must exist in the base type `T`.***
|
|
2004
|
+
*
|
|
2005
|
+
* - If `true`, all keys of `U` must exist in `T`.
|
|
2006
|
+
* - If `false`, additional keys from `U` are allowed and will be added
|
|
2007
|
+
* to the resulting type.
|
|
2008
|
+
*
|
|
2009
|
+
* @default true
|
|
2010
|
+
*/
|
|
2011
|
+
strictKeys: boolean;
|
|
2012
|
+
/** * ***Options forwarded to {@link Prettify | `Prettify`}.***
|
|
2013
|
+
*
|
|
2014
|
+
* Controls how the resulting type is normalized.
|
|
2015
|
+
*/
|
|
2016
|
+
prettifyOptions?: PrettifyOptions;
|
|
2017
|
+
};
|
|
2018
|
+
type StrictOverrideConstraint<T, U, Strict extends boolean> = Strict extends true ? { [K in keyof U]: K extends keyof T ? unknown : never } : unknown;
|
|
2019
|
+
type ResolvePrettifyOptions<O extends OverrideTypesOptions> = O["prettifyOptions"] extends PrettifyOptions ? O["prettifyOptions"] : DefaultPrettifyOptions;
|
|
2020
|
+
/** --------------------------------------------------
|
|
2021
|
+
* * ***Utility Type: `OverrideTypes`.***
|
|
2022
|
+
* --------------------------------------------------
|
|
2023
|
+
* Overrides properties in type `T` using properties from type `U`.
|
|
2024
|
+
*
|
|
2025
|
+
* Keys that exist in both `T` and `U` will take the value type from `U`,
|
|
2026
|
+
* while all other properties from `T` remain unchanged.
|
|
2027
|
+
*
|
|
2028
|
+
* The behavior can be configured using {@link OverrideTypesOptions}.
|
|
2029
|
+
*
|
|
2030
|
+
* @template T - The base object type whose properties will be overridden.
|
|
2031
|
+
* @template U - The object type providing overriding property types.
|
|
2032
|
+
* @template Options - Configuration controlling override behavior.
|
|
2033
|
+
*
|
|
2034
|
+
* @remarks
|
|
2035
|
+
* - When `Options["strictKeys"]` is `true` (default), all keys in `U`
|
|
2036
|
+
* **must already exist in `T`**.
|
|
2037
|
+
* - When `strictKeys` is `false`, `U` may introduce **additional keys**
|
|
2038
|
+
* which will be added to the resulting type.
|
|
2039
|
+
* - The resulting type is normalized using {@link Prettify}.
|
|
2040
|
+
*
|
|
2041
|
+
* @example
|
|
2042
|
+
* // Basic override
|
|
2043
|
+
* type A = { a: number; b: string };
|
|
2044
|
+
* type B = { b: boolean };
|
|
2045
|
+
* type C = OverrideTypes<A, B>;
|
|
2046
|
+
* // Result:
|
|
2047
|
+
* // {
|
|
2048
|
+
* // a: number;
|
|
2049
|
+
* // b: boolean;
|
|
2050
|
+
* // }
|
|
2051
|
+
*
|
|
2052
|
+
* @example
|
|
2053
|
+
* // Strict key enforcement (default)
|
|
2054
|
+
* type A = { a: number; b: string };
|
|
2055
|
+
* type B = { x: string[]; b: boolean };
|
|
2056
|
+
* // @ts-expect-error
|
|
2057
|
+
* type C = OverrideTypes<A, B>;
|
|
2058
|
+
* // Error: "x" is not assignable to keyof A
|
|
2059
|
+
*
|
|
2060
|
+
* @example
|
|
2061
|
+
* // Allow additional keys
|
|
2062
|
+
* type A = { a: number; b: string };
|
|
2063
|
+
* type B = { x: string[]; b: boolean };
|
|
2064
|
+
* type C = OverrideTypes<A, B, { strictKeys: false }>;
|
|
2065
|
+
* // Result:
|
|
2066
|
+
* // {
|
|
2067
|
+
* // a: number;
|
|
2068
|
+
* // b: boolean;
|
|
2069
|
+
* // x: string[];
|
|
2070
|
+
* // }
|
|
2071
|
+
*
|
|
2072
|
+
* @example
|
|
2073
|
+
* // Custom Prettify options
|
|
2074
|
+
* type A = { a: number; b: string };
|
|
2075
|
+
* type B = { b: boolean };
|
|
2076
|
+
* type C = OverrideTypes<
|
|
2077
|
+
* A,
|
|
2078
|
+
* B,
|
|
2079
|
+
* {
|
|
2080
|
+
* strictKeys: true;
|
|
2081
|
+
* prettifyOptions: { skipPrettify: true };
|
|
2082
|
+
* }
|
|
2083
|
+
* >;
|
|
2084
|
+
*/
|
|
2085
|
+
type OverrideTypes<T, U extends StrictOverrideConstraint<T, U, Options["strictKeys"]>, Options extends OverrideTypesOptions = {
|
|
2086
|
+
strictKeys: true;
|
|
2087
|
+
prettifyOptions: DefaultPrettifyOptions;
|
|
2088
|
+
}> = Options["strictKeys"] extends true ? Exclude<keyof U, keyof T> extends never ? Prettify<OmitStrict<T, Extract<keyof U, keyof T>, ResolvePrettifyOptions<Options>> & U, ResolvePrettifyOptions<Options>> : never : Prettify<OmitStrict<T, Extract<keyof U, keyof T>, ResolvePrettifyOptions<Options>> & { [K in keyof U]: U[K] }, ResolvePrettifyOptions<Options>>;
|
|
2089
|
+
/** --------------------------------------------------
|
|
2090
|
+
* * ***Utility Type: `PickStrict`.***
|
|
2091
|
+
* --------------------------------------------------
|
|
2092
|
+
* **Utility type that behaves exactly like the native `Pick<T, K>`,
|
|
2093
|
+
* but can help with type inference and IDE autocomplete in stricter scenarios.**
|
|
2094
|
+
* @template T - The base object type.
|
|
2095
|
+
* @template K - The keys from `T` to be picked.
|
|
2096
|
+
* @example
|
|
2097
|
+
* ```ts
|
|
2098
|
+
* type A = { a: number; b: string; c: boolean };
|
|
2099
|
+
* type B = PickStrict<A, 'a' | 'c'>;
|
|
2100
|
+
* // ➔ { a: number; c: boolean }
|
|
2101
|
+
* ```
|
|
2102
|
+
*/
|
|
2103
|
+
type PickStrict<T, K extends keyof T> = Pick<T, K>;
|
|
2104
|
+
interface CustomPromiseLike<OnSuccess, OnError> {
|
|
2105
|
+
/**
|
|
2106
|
+
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
|
2107
|
+
* @param onfulfilled The callback to execute when the Promise is resolved.
|
|
2108
|
+
* @param onrejected The callback to execute when the Promise is rejected.
|
|
2109
|
+
* @returns A Promise for the completion of which ever callback is executed.
|
|
2110
|
+
*/
|
|
2111
|
+
then<TResult1 = OnSuccess, TResult2 = never>(onfulfilled?: ((value: OnSuccess) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: OnError) => TResult2 | PromiseLike<TResult2>) | null | undefined): CustomPromiseType<TResult1 | TResult2, OnError>;
|
|
2112
|
+
/**
|
|
2113
|
+
* Attaches a callback for only the rejection of the Promise.
|
|
2114
|
+
* @param onrejected The callback to execute when the Promise is rejected.
|
|
2115
|
+
* @returns A Promise for the completion of the callback.
|
|
2116
|
+
*/
|
|
2117
|
+
catch<TResult = never>(onrejected?: ((reason: OnError) => TResult | PromiseLike<TResult>) | null | undefined): CustomPromiseType<OnSuccess | TResult, OnError>;
|
|
2118
|
+
/**
|
|
2119
|
+
* Registers a callback to be invoked **exactly once** when the
|
|
2120
|
+
* promise settles, with access to both the resolved value and
|
|
2121
|
+
* the rejection reason.
|
|
2122
|
+
*
|
|
2123
|
+
* If the promise is already settled when `finish` is called,
|
|
2124
|
+
* the callback executes immediately on the same tick.
|
|
2125
|
+
*
|
|
2126
|
+
* @param cb Callback receiving the final `(value, error)`.
|
|
2127
|
+
* @returns `this` for fluent chaining.
|
|
2128
|
+
*/
|
|
2129
|
+
finish(cb: (value: OnSuccess | undefined, error: OnError | undefined) => void): CustomPromiseType<OnSuccess, OnError>;
|
|
2130
|
+
}
|
|
2131
|
+
/** --------------------------------------------------
|
|
2132
|
+
* * ***Utility Type: `CustomPromiseType`.***
|
|
2133
|
+
* --------------------------------------------------
|
|
2134
|
+
* **Extends the native `Promise` type to provide explicit typing
|
|
2135
|
+
* for both the resolved (`onSuccess`) and rejected (`onError`) values,
|
|
2136
|
+
* plus an optional `finish` hook.**
|
|
2137
|
+
* - **Behavior:**
|
|
2138
|
+
* - ✅ **Strongly types** `success`, `error`, and `finish` handlers.
|
|
2139
|
+
* - ⚙️ `finish` runs exactly once after the promise settles (similar to `finish`).
|
|
2140
|
+
* @template OnSuccess - The type of the fulfilled value.
|
|
2141
|
+
* @template OnError - The type of the rejection reason, defaults to `unknown`.
|
|
2142
|
+
* @example
|
|
2143
|
+
* ```ts
|
|
2144
|
+
* import type { CustomPromiseType } from "@rzl-zone/ts-types-plus";
|
|
2145
|
+
* import { CustomPromise } from "@rzl-zone/utils-js/promises";
|
|
2146
|
+
*
|
|
2147
|
+
* const fetchUser = (): CustomPromiseType<User, ApiError> =>
|
|
2148
|
+
* new CustomsPromise<User, ApiError>((resolve, reject) => {
|
|
2149
|
+
* apiCall().then(resolve).catch(reject);
|
|
2150
|
+
* });
|
|
2151
|
+
*
|
|
2152
|
+
* fetchUser()
|
|
2153
|
+
* .then(user => console.log(user))
|
|
2154
|
+
* .catch(err => console.error(err))
|
|
2155
|
+
* .finish((result, error) => {
|
|
2156
|
+
* console.log("always runs", { result, error });
|
|
2157
|
+
* });
|
|
2158
|
+
* ```
|
|
2159
|
+
*/
|
|
2160
|
+
type CustomPromiseType<OnSuccess, OnError = unknown> = CustomPromiseLike<OnSuccess, OnError>;
|
|
2161
|
+
/** -------------------------------------------------------
|
|
2162
|
+
* * ***Utility Type: `ReadonlyOnly`.***
|
|
2163
|
+
* -------------------------------------------------------
|
|
2164
|
+
* **Makes the specified keys `K` of an object type `T` readonly,
|
|
2165
|
+
* while leaving the other properties mutable.**
|
|
2166
|
+
* @template T - The object type.
|
|
2167
|
+
* @template K - Keys of `T` to make readonly.
|
|
2168
|
+
* @template PrettifyOptions - Options controlling whether the resulting
|
|
2169
|
+
* type should be normalized using the `Prettify` helper.
|
|
2170
|
+
* @example
|
|
2171
|
+
* ```ts
|
|
2172
|
+
* type T0 = ReadonlyOnly<{ a: string; b: number }, 'a'>;
|
|
2173
|
+
* // ➔ { readonly a: string; b: number }
|
|
2174
|
+
*
|
|
2175
|
+
* type T1 = ReadonlyOnly<{ x: boolean; y: number; z: string }, 'y' | 'z'>;
|
|
2176
|
+
* // ➔ { x: boolean; readonly y: number; readonly z: string }
|
|
2177
|
+
* ```
|
|
2178
|
+
*/
|
|
2179
|
+
export { OverrideTypes as A, NonPlainObject as C, NumberRangeUnion as D, Nullish as E, Stringify as F, Trim as I, TypedArray as L, PickStrict as M, Prettify as N, OmitStrict as O, RemoveEmptyArrayElements as P, WebApiObjects as R, Nilable as S, NullToUndefined as T, IsNever as _, CharAt as a, KeepNull as b, ExtractStrict as c, IfNonEmptyArray as d, IfNotExtends as f, IsEmptyString as g, IsArray as h, AnyString as i, ParseNumber as j, OrArr as k, FixNeverArrayRecursive as l, IsAny as m, AndArr as n, CustomPromiseType as o, IntlObjects as p, AnyFunction as r, Extends as s, AnObjectNonArray as t, IfExtends as u, IsPositive as v, NormalizeEmptyArraysRecursive as w, KeepUndef as x, IsStringLiteral as y };
|