ts-type-predicates 1.0.9 → 1.0.12

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/CHANGELOG.md CHANGED
@@ -3,6 +3,51 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.0.12](https://github.com/bluelovers/ws-ts-type/compare/ts-type-predicates@1.0.10...ts-type-predicates@1.0.12) (2026-03-15)
7
+
8
+
9
+
10
+ ### ✨ Features
11
+
12
+ * **is-array:** 新增唯讀陣列類型斷言支援及完善文檔說明 ([4f0d97d](https://github.com/bluelovers/ws-ts-type/commit/4f0d97d86c93c5a82a66712695fa69cd5a78344a))
13
+
14
+
15
+ ### 📚 Documentation
16
+
17
+ * **ts-type-predicates:** 新增 typePredicates 強化 Narrowing 用法說明 ([a0eeb18](https://github.com/bluelovers/ws-ts-type/commit/a0eeb188a5d67f3983d8986955bcab70eaf52497))
18
+
19
+
20
+ ### 🛠 Build System
21
+
22
+ * 優化類型定義輸出流程並移除 snapshot 更新標誌 ([5b9aeca](https://github.com/bluelovers/ws-ts-type/commit/5b9aeca2434e581f818d8872ffde43236f203e57))
23
+
24
+
25
+ ### 🔖 Miscellaneous
26
+
27
+ * . ([43bb6af](https://github.com/bluelovers/ws-ts-type/commit/43bb6afdf390a090c87bdb872e5b6f9fd9932669))
28
+
29
+
30
+
31
+ ## [1.0.10](https://github.com/bluelovers/ws-ts-type/compare/ts-type-predicates@1.0.9...ts-type-predicates@1.0.10) (2026-03-07)
32
+
33
+
34
+
35
+ ### 📚 Documentation
36
+
37
+ * enhance documentation and JSDoc comments across multiple packages ([88ee99b](https://github.com/bluelovers/ws-ts-type/commit/88ee99b3a489645ca53093357cc3523dbe7996e0))
38
+
39
+
40
+ ### 🛠 Build System
41
+
42
+ * 更新多個套件的 test 指令為 jest ([61ea53b](https://github.com/bluelovers/ws-ts-type/commit/61ea53bf15fc3ed0e216793200604ae5a52079c9))
43
+
44
+
45
+ ### ♻️ Chores
46
+
47
+ * migrate from yarn to pnpm and enhance test infrastructure ([8a5daa2](https://github.com/bluelovers/ws-ts-type/commit/8a5daa2f2022eaf025c3349d4fe5dc8971f8c077))
48
+
49
+
50
+
6
51
  ## [1.0.9](https://github.com/bluelovers/ws-ts-type/compare/ts-type-predicates@1.0.8...ts-type-predicates@1.0.9) (2022-10-10)
7
52
 
8
53
 
package/README.md CHANGED
@@ -1,8 +1,27 @@
1
- # README.md
1
+ # ts-type-predicates
2
2
 
3
- use asserts for make type predicates work
3
+ 使用斷言(assert)讓類型斷言(type predicates)運作的實用工具函式
4
4
 
5
- ## install
5
+ Use asserts to make type predicates work with better runtime validation
6
+
7
+ ---
8
+
9
+ ## 功能特點 / Features
10
+
11
+ - 結合 TypeScript 斷言函式與類型斷言功能
12
+ - Combine TypeScript assertion functions with type predicate functionality
13
+ - 支援運行時驗證與編譯時類型縮小
14
+ - Support runtime validation and compile-time type narrowing
15
+ - 可自訂錯誤訊息
16
+ - Customizable error messages
17
+ - 可選擇只做類型收窄不拋出錯誤
18
+ - Optional type narrowing without throwing errors
19
+ - 可用於強化替代 Narrowing
20
+ - Can be used to enhance or replace Narrowing
21
+
22
+ ---
23
+
24
+ ## 安裝 / Install
6
25
 
7
26
  ```bash
8
27
  yarn add ts-type-predicates
@@ -10,3 +29,96 @@ yarn-tool add ts-type-predicates
10
29
  yt add ts-type-predicates
11
30
  ```
12
31
 
32
+ ---
33
+
34
+ ## 使用範例 / Usage Examples
35
+
36
+ ### 基本用法
37
+
38
+ ```typescript
39
+ import { typePredicates, typeNarrowed } from 'ts-type-predicates';
40
+
41
+ // 使用斷言函式 - 失敗時拋出錯誤
42
+ function processValue(value: string | number) {
43
+ typePredicates<string>(value, typeof value === 'string');
44
+ // 現在 TypeScript 知道 value 是 string
45
+ console.log(value.toUpperCase());
46
+ }
47
+
48
+ // 使用類型收窄 - 回傳布林值
49
+ function checkValue(value: unknown) {
50
+ if (typeNarrowed<string>(value, typeof value === 'string')) {
51
+ console.log(value.length);
52
+ }
53
+ }
54
+ ```
55
+
56
+ ### 參數省略
57
+
58
+ 參數除了第一個以外都能省略:
59
+
60
+ ```typescript
61
+ import { typePredicates } from 'ts-type-predicates';
62
+
63
+ // 只有第一個參數是必需的
64
+ typePredicates<string>(value);
65
+ ```
66
+
67
+ ### 強化替代 Narrowing
68
+
69
+ 當標準的 Narrowing 無法正確收窄類型時,可以使用 `typePredicates` 強制收窄:
70
+
71
+ ```typescript
72
+ import { typePredicates } from 'ts-type-predicates';
73
+
74
+ // Narrowing 無法處理的情況
75
+ type Mixed = { type: 'a'; value: string } | { type: 'b'; value: number };
76
+
77
+ function process(data: Mixed) {
78
+ // ❌ Narrowing 無法正確收窄 value 的類型
79
+ if (data.type === 'a') {
80
+ // data.value 仍然是 string | number
81
+ console.log(data.value.toUpperCase()); // 錯誤
82
+ }
83
+
84
+ // ✅ 使用 typePredicates 強制收窄 - 更精簡的寫法 (需要配合使用 @ts-ignore 註釋)
85
+ if (typePredicates<string>(data.value, data.type === 'a')) {
86
+ // data.value 現在正確收窄為 string
87
+ console.log(data.value.toUpperCase()); // 正確
88
+ }
89
+ }
90
+ ```
91
+
92
+ ### 忽略表達式結果
93
+
94
+ 當只需要類型收窄,不需要運行時驗證時:
95
+
96
+ ```typescript
97
+ import { typePredicates } from 'ts-type-predicates';
98
+
99
+ // 只做類型收窄,不拋出錯誤
100
+ function narrowValue(value: unknown) {
101
+ typePredicates<string>(value, typeof value === 'string', undefined, true);
102
+ // value 現在被收窄為 string(但運行時不驗證)
103
+ console.log(value.toUpperCase());
104
+ }
105
+ ```
106
+
107
+ ---
108
+
109
+ ## 與標準 Narrowing 的比較
110
+
111
+ | 特性 | Narrowing(內建) | typePredicates |
112
+ |------|-------------------|----------------|
113
+ | 語法 | `if (typeof x === "string")` | `typePredicates<string>(x)` |
114
+ | 彈性 | 有限 | 可自訂任意邏輯 |
115
+ | 錯誤處理 | 無 | 可拋出自訂錯誤 |
116
+ | 強制收窄 | 無法 | 可以 |
117
+ | 複雜類型 | 需多重檢查 | 可一次完成 |
118
+
119
+ ---
120
+
121
+ ## 相關資源
122
+
123
+ - [TypeScript 官方文件 - Type Predicates](https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates)
124
+ - [TypeScript 官方文件 - Assertion Functions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions)
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  'use strict'
3
3
 
4
- if (typeof process !== 'undefined' && process.env.NODE_ENV === 'production') {
5
- module.exports = require('./index.cjs.production.min.cjs')
6
- } else {
4
+ if (typeof process !== 'undefined' && process.env.NODE_ENV !== 'production') {
7
5
  module.exports = require('./index.cjs.development.cjs')
6
+ } else {
7
+ module.exports = require('./index.cjs.production.min.cjs')
8
8
  }
@@ -4,20 +4,60 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var assert = require('assert');
6
6
 
7
+ /// <reference types="node" />
8
+ /**
9
+ * 處理表達式,回傳布林值結果
10
+ * Handle expression and return boolean result
11
+ *
12
+ * @param actual - 實際值 / Actual value
13
+ * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function
14
+ * @returns 布林值結果 / Boolean result
15
+ */
7
16
  function _handleExpression(actual, expression = true) {
8
- var _expression;
9
-
10
- (_expression = expression) !== null && _expression !== void 0 ? _expression : expression = true;
11
-
17
+ expression !== null && expression !== void 0 ? expression : expression = true;
12
18
  if (typeof expression === 'function') {
13
19
  expression = !!expression(actual);
14
20
  }
15
-
16
21
  return expression;
17
22
  }
23
+ /**
24
+ * 使用斷言(assert)讓類型斷言(type predicates)運作
25
+ * Use asserts for make type predicates work
26
+ *
27
+ * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,
28
+ * 允許在運行時驗證類型並在編譯時縮小類型範圍
29
+ *
30
+ * @param T - 預期的類型 / Expected type
31
+ * @param actual - 實際值 / Actual value
32
+ * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)
33
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
34
+ * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)
35
+ * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false
36
+ *
37
+ * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates
38
+ * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
39
+ *
40
+ * @example
41
+ * // 基本用法:失敗時拋出錯誤
42
+ * typePredicates<string>(value, typeof value === 'string');
43
+ *
44
+ * @example
45
+ * // 參數除了第一個以外都能省略
46
+ * typePredicates<string>(value);
47
+ *
48
+ * @example
49
+ * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)
50
+ * if (typePredicates<string>(data.value, data.type === 'a')) {
51
+ * // data.value 現在正確收窄為 string
52
+ * console.log(data.value.toUpperCase());
53
+ * }
54
+ *
55
+ * @example
56
+ * // 忽略表達式結果,只做類型收窄,不拋出錯誤
57
+ * typePredicates<string>(value, typeof value === 'string', undefined, true);
58
+ */
18
59
  function typePredicates(actual, expression = true, message, ignoreExpression) {
19
60
  expression = _handleExpression(actual, expression);
20
-
21
61
  if (expression !== true && ignoreExpression !== true) {
22
62
  throw new assert.AssertionError({
23
63
  message: message !== null && message !== void 0 ? message : `actual ${actual} not as expected`,
@@ -26,19 +66,38 @@ function typePredicates(actual, expression = true, message, ignoreExpression) {
26
66
  operator: 'typePredicates'
27
67
  });
28
68
  }
69
+ // @ts-ignore
70
+ return expression;
29
71
  }
72
+ /**
73
+ * 類型收窄函式,回傳類型斷言結果
74
+ * Type narrowing function, returns type predicate result
75
+ *
76
+ * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型
77
+ * 可用於需要條件邏輯而非斷言的場景
78
+ *
79
+ * @param T - 預期的類型 / Expected type
80
+ * @param actual - 實際值 / Actual value
81
+ * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)
82
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
83
+ * @returns 是否符合預期類型 / Whether it matches the expected type
84
+ *
85
+ * @example
86
+ * // 使用 typeNarrowed - 回傳布林值
87
+ * if (typeNarrowed<string>(value, typeof value === 'string')) {
88
+ * console.log(value.length);
89
+ * }
90
+ */
30
91
  function typeNarrowed(actual, expression = true, message) {
31
92
  expression = _handleExpression(actual, expression);
32
-
33
93
  if (expression !== true) {
34
94
  expression = false;
35
95
  }
36
-
37
96
  return expression;
38
97
  }
39
98
 
40
99
  exports._handleExpression = _handleExpression;
41
- exports["default"] = typePredicates;
100
+ exports.default = typePredicates;
42
101
  exports.typeNarrowed = typeNarrowed;
43
102
  exports.typePredicates = typePredicates;
44
103
  //# sourceMappingURL=index.cjs.development.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.development.cjs","sources":["../src/index.ts"],"sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","message","typeNarrowed","actual"],"mappings":";;;;;;;;;;;EAAA,IAAwC,OAAA,UAAA,KAAA,UAAA,EAAA;cAI7B,eAAU;AAInB,GAAA;;AAGD,EAAA,OAAAA,UAAA,CAAA;;AAWA,SAAA,cAAA,CAAA,MAAA,EAAA,UAAA,GAAA,IAAA,EAAA,OAAA,EAAA,gBAAA,EAAA;YAIC,oBAAU;;AACT,EAAA,IAAA,UAAA,KAAA,IAAA,IAAA,gBAAA,KAAA,IAAA,EAAA;;MAEAC;;;;;AAMG,GAAA;AAEL,CAAA;SAIWC,aAAAC,QAASH,UAAA,SAAAC,SAAA;AAGpBD,EAAAA,UAAA,oBAAiB,CAAjB,MAAA,EAAA,UAAA,CAAA,CAAA;;MAGDA,UAAA,KAAA,IAAA,EAAA;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.development.cjs","sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","actual","expected","operator"],"mappings":";;;;;;;;AAoEG;;AApEH;AACA;;;;;;;;AAUA,GAAA;SAEWA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAuDRC,MAAA;AAEAC,MAAAA,QAAC,EAAAF,UAAA;MAGUG,QAAA,EAAA,gBAAA;AAEb,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,27 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("assert");function _handleExpression(e,r=!0){var t;return null!==(t=r)&&void 0!==t||(r=!0),"function"==typeof r&&(r=!!r(e)),r}function typePredicates(r,t=!0,s,n){if(!0!==(t=_handleExpression(r,t))&&!0!==n)throw new e.AssertionError({message:null!=s?s:`actual ${r} not as expected`,actual:r,expected:t,operator:"typePredicates"})}exports._handleExpression=_handleExpression,exports.default=typePredicates,exports.typeNarrowed=function typeNarrowed(e,r=!0,t){return!0!==(r=_handleExpression(e,r))&&(r=!1),r},exports.typePredicates=typePredicates;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: !0
5
+ });
6
+
7
+ var e = require("assert");
8
+
9
+ function _handleExpression(e, r = !0) {
10
+ return null != r || (r = !0), "function" == typeof r && (r = !!r(e)), r;
11
+ }
12
+
13
+ function typePredicates(r, t = !0, s, n) {
14
+ if (!0 !== (t = _handleExpression(r, t)) && !0 !== n) throw new e.AssertionError({
15
+ message: null != s ? s : `actual ${r} not as expected`,
16
+ actual: r,
17
+ expected: t,
18
+ operator: "typePredicates"
19
+ });
20
+ return t;
21
+ }
22
+
23
+ exports._handleExpression = _handleExpression, exports.default = typePredicates,
24
+ exports.typeNarrowed = function typeNarrowed(e, r = !0, t) {
25
+ return !0 !== (r = _handleExpression(e, r)) && (r = !1), r;
26
+ }, exports.typePredicates = typePredicates;
2
27
  //# sourceMappingURL=index.cjs.production.min.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","typePredicates","actual","message","ignoreExpression","typeNarrowed"],"mappings":"qIAWC,wCAXuC,mBAAAA,cAWvCA,EAWA,SAAAC,eAAAC,EAAAF,GAAA,EAAAG,EAAAC,GAKE,IAAA,iCAAA,IAAAA,8BAEAD,+FAQF,0GAIWE,aAAAH,EAASF,KAAAG,UAMrB,KAHCH,oBAAAE,EAAAF"}
1
+ {"version":3,"file":"index.cjs.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","actual","expected","operator"],"mappings":";;;;;;;;;wEAaWA;;;;;;IAuDRC;IAEAC,UAACF;IAGUG,UAAA;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,15 +1,67 @@
1
+ /**
2
+ * 處理表達式,回傳布林值結果
3
+ * Handle expression and return boolean result
4
+ *
5
+ * @param actual - 實際值 / Actual value
6
+ * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function
7
+ * @returns 布林值結果 / Boolean result
8
+ */
1
9
  export declare function _handleExpression<T, P = any>(actual: T | P, expression?: boolean | ((actual: T | P) => any)): boolean;
2
10
  /**
3
- * use asserts for make type predicates work
11
+ * 使用斷言(assert)讓類型斷言(type predicates)運作
12
+ * Use asserts for make type predicates work
13
+ *
14
+ * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,
15
+ * 允許在運行時驗證類型並在編譯時縮小類型範圍
16
+ *
17
+ * @param T - 預期的類型 / Expected type
18
+ * @param actual - 實際值 / Actual value
19
+ * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)
20
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
21
+ * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)
22
+ * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false
4
23
  *
5
24
  * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates
6
25
  * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
26
+ *
27
+ * @example
28
+ * // 基本用法:失敗時拋出錯誤
29
+ * typePredicates<string>(value, typeof value === 'string');
30
+ *
31
+ * @example
32
+ * // 參數除了第一個以外都能省略
33
+ * typePredicates<string>(value);
34
+ *
35
+ * @example
36
+ * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)
37
+ * if (typePredicates<string>(data.value, data.type === 'a')) {
38
+ * // data.value 現在正確收窄為 string
39
+ * console.log(data.value.toUpperCase());
40
+ * }
41
+ *
42
+ * @example
43
+ * // 忽略表達式結果,只做類型收窄,不拋出錯誤
44
+ * typePredicates<string>(value, typeof value === 'string', undefined, true);
7
45
  */
8
46
  export declare function typePredicates<T, P = any>(actual: T | P, expression?: boolean | ((actual: T | P) => any), message?: string, ignoreExpression?: boolean): asserts actual is T;
47
+ /**
48
+ * 類型收窄函式,回傳類型斷言結果
49
+ * Type narrowing function, returns type predicate result
50
+ *
51
+ * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型
52
+ * 可用於需要條件邏輯而非斷言的場景
53
+ *
54
+ * @param T - 預期的類型 / Expected type
55
+ * @param actual - 實際值 / Actual value
56
+ * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)
57
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
58
+ * @returns 是否符合預期類型 / Whether it matches the expected type
59
+ *
60
+ * @example
61
+ * // 使用 typeNarrowed - 回傳布林值
62
+ * if (typeNarrowed<string>(value, typeof value === 'string')) {
63
+ * console.log(value.length);
64
+ * }
65
+ */
9
66
  export declare function typeNarrowed<T, P = any>(actual: T | P, expression?: boolean | ((actual: T | P) => any), message?: string): actual is T;
10
-
11
- export {
12
- typePredicates as default,
13
- };
14
-
15
- export {};
67
+ export default typePredicates;
@@ -1,9 +1,7 @@
1
1
  import { AssertionError as e } from "assert";
2
2
 
3
3
  function _handleExpression(e, t = !0) {
4
- var r;
5
- return null !== (r = t) && void 0 !== r || (t = !0), "function" == typeof t && (t = !!t(e)),
6
- t;
4
+ return null != t || (t = !0), "function" == typeof t && (t = !!t(e)), t;
7
5
  }
8
6
 
9
7
  function typePredicates(t, r = !0, n, a) {
@@ -13,6 +11,7 @@ function typePredicates(t, r = !0, n, a) {
13
11
  expected: r,
14
12
  operator: "typePredicates"
15
13
  });
14
+ return r;
16
15
  }
17
16
 
18
17
  function typeNarrowed(e, t = !0, r) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.mjs","sources":["../src/index.ts"],"sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","typePredicates","actual","message","ignoreExpression","typeNarrowed"],"mappings":";;;;EAWC,qDAXuC,qBAAAA;EAWvCA;;;AAWA,SAAAC,eAAAC,GAAAF,KAAA,GAAAG,GAAAC;EAKE,KAAA,wCAAA,MAAAA;IAEAD;;;;;AAQF;;SAIWE,aAAAH,GAASF,QAAAG;UAMrB,OAHCH,sBAAAE,GAAAF;;;"}
1
+ {"version":3,"file":"index.esm.mjs","sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","actual","expected","operator"],"mappings":";;;wEAaWA;;;;;;IAuDRC;IAEAC,UAACF;IAGUG,UAAA;;;;;;;;;"}
@@ -4,20 +4,60 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TsTypePredicates = {}, global.assert));
5
5
  })(this, (function (exports, assert) { 'use strict';
6
6
 
7
+ /// <reference types="node" />
8
+ /**
9
+ * 處理表達式,回傳布林值結果
10
+ * Handle expression and return boolean result
11
+ *
12
+ * @param actual - 實際值 / Actual value
13
+ * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function
14
+ * @returns 布林值結果 / Boolean result
15
+ */
7
16
  function _handleExpression(actual, expression = true) {
8
- var _expression;
9
-
10
- (_expression = expression) !== null && _expression !== void 0 ? _expression : expression = true;
11
-
17
+ expression !== null && expression !== void 0 ? expression : expression = true;
12
18
  if (typeof expression === 'function') {
13
19
  expression = !!expression(actual);
14
20
  }
15
-
16
21
  return expression;
17
22
  }
23
+ /**
24
+ * 使用斷言(assert)讓類型斷言(type predicates)運作
25
+ * Use asserts for make type predicates work
26
+ *
27
+ * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,
28
+ * 允許在運行時驗證類型並在編譯時縮小類型範圍
29
+ *
30
+ * @param T - 預期的類型 / Expected type
31
+ * @param actual - 實際值 / Actual value
32
+ * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)
33
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
34
+ * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)
35
+ * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false
36
+ *
37
+ * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates
38
+ * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
39
+ *
40
+ * @example
41
+ * // 基本用法:失敗時拋出錯誤
42
+ * typePredicates<string>(value, typeof value === 'string');
43
+ *
44
+ * @example
45
+ * // 參數除了第一個以外都能省略
46
+ * typePredicates<string>(value);
47
+ *
48
+ * @example
49
+ * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)
50
+ * if (typePredicates<string>(data.value, data.type === 'a')) {
51
+ * // data.value 現在正確收窄為 string
52
+ * console.log(data.value.toUpperCase());
53
+ * }
54
+ *
55
+ * @example
56
+ * // 忽略表達式結果,只做類型收窄,不拋出錯誤
57
+ * typePredicates<string>(value, typeof value === 'string', undefined, true);
58
+ */
18
59
  function typePredicates(actual, expression = true, message, ignoreExpression) {
19
60
  expression = _handleExpression(actual, expression);
20
-
21
61
  if (expression !== true && ignoreExpression !== true) {
22
62
  throw new assert.AssertionError({
23
63
  message: message !== null && message !== void 0 ? message : `actual ${actual} not as expected`,
@@ -26,19 +66,38 @@
26
66
  operator: 'typePredicates'
27
67
  });
28
68
  }
69
+ // @ts-ignore
70
+ return expression;
29
71
  }
72
+ /**
73
+ * 類型收窄函式,回傳類型斷言結果
74
+ * Type narrowing function, returns type predicate result
75
+ *
76
+ * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型
77
+ * 可用於需要條件邏輯而非斷言的場景
78
+ *
79
+ * @param T - 預期的類型 / Expected type
80
+ * @param actual - 實際值 / Actual value
81
+ * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)
82
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
83
+ * @returns 是否符合預期類型 / Whether it matches the expected type
84
+ *
85
+ * @example
86
+ * // 使用 typeNarrowed - 回傳布林值
87
+ * if (typeNarrowed<string>(value, typeof value === 'string')) {
88
+ * console.log(value.length);
89
+ * }
90
+ */
30
91
  function typeNarrowed(actual, expression = true, message) {
31
92
  expression = _handleExpression(actual, expression);
32
-
33
93
  if (expression !== true) {
34
94
  expression = false;
35
95
  }
36
-
37
96
  return expression;
38
97
  }
39
98
 
40
99
  exports._handleExpression = _handleExpression;
41
- exports["default"] = typePredicates;
100
+ exports.default = typePredicates;
42
101
  exports.typeNarrowed = typeNarrowed;
43
102
  exports.typePredicates = typePredicates;
44
103
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.development.cjs","sources":["../src/index.ts"],"sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","message","typeNarrowed","actual"],"mappings":";;;;;;;;;;;GAAA,IAAwC,OAAA,UAAA,KAAA,UAAA,EAAA;eAI7B,eAAU;CAInB,GAAA;;CAGD,EAAA,OAAAA,UAAA,CAAA;;CAWA,SAAA,cAAA,CAAA,MAAA,EAAA,UAAA,GAAA,IAAA,EAAA,OAAA,EAAA,gBAAA,EAAA;aAIC,oBAAU;;CACT,EAAA,IAAA,UAAA,KAAA,IAAA,IAAA,gBAAA,KAAA,IAAA,EAAA;;OAEAC;;;;;CAMG,GAAA;CAEL,CAAA;UAIWC,aAAAC,QAASH,UAAA,SAAAC,SAAA;CAGpBD,EAAAA,UAAA,oBAAiB,CAAjB,MAAA,EAAA,UAAA,CAAA,CAAA;;OAGDA,UAAA,KAAA,IAAA,EAAA;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.umd.development.cjs","sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","actual","expected","operator"],"mappings":";;;;;;;;CAoEG;;CApEH;CACA;;;;;;;;CAUA,GAAA;UAEWA,UAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuDRC,MAAA;CAEAC,MAAAA,QAAC,EAAAF,UAAA;OAGUG,QAAA,EAAA,gBAAA;CAEb,KAAA,CAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,23 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("assert")):"function"==typeof define&&define.amd?define(["exports","assert"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TsTypePredicates={},e.assert)}(this,(function(e,t){"use strict";function _handleExpression(e,t=!0){var n;return null!==(n=t)&&void 0!==n||(t=!0),"function"==typeof t&&(t=!!t(e)),t}function typePredicates(e,n=!0,r,s){if(!0!==(n=_handleExpression(e,n))&&!0!==s)throw new t.AssertionError({message:null!=r?r:`actual ${e} not as expected`,actual:e,expected:n,operator:"typePredicates"})}e._handleExpression=_handleExpression,e.default=typePredicates,e.typeNarrowed=function typeNarrowed(e,t=!0,n){return!0!==(t=_handleExpression(e,t))&&(t=!1),t},e.typePredicates=typePredicates,Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ !function(e, t) {
2
+ "object" == typeof exports && "undefined" != typeof module ? t(exports, require("assert")) : "function" == typeof define && define.amd ? define([ "exports", "assert" ], t) : t((e = "undefined" != typeof globalThis ? globalThis : e || self).TsTypePredicates = {}, e.assert);
3
+ }(this, function(e, t) {
4
+ "use strict";
5
+ function _handleExpression(e, t = !0) {
6
+ return null != t || (t = !0), "function" == typeof t && (t = !!t(e)), t;
7
+ }
8
+ function typePredicates(e, n = !0, r, s) {
9
+ if (!0 !== (n = _handleExpression(e, n)) && !0 !== s) throw new t.AssertionError({
10
+ message: null != r ? r : `actual ${e} not as expected`,
11
+ actual: e,
12
+ expected: n,
13
+ operator: "typePredicates"
14
+ });
15
+ return n;
16
+ }
17
+ e._handleExpression = _handleExpression, e.default = typePredicates, e.typeNarrowed = function typeNarrowed(e, t = !0, n) {
18
+ return !0 !== (t = _handleExpression(e, t)) && (t = !1), t;
19
+ }, e.typePredicates = typePredicates, Object.defineProperty(e, "__esModule", {
20
+ value: !0
21
+ });
22
+ });
2
23
  //# sourceMappingURL=index.umd.production.min.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","typePredicates","actual","message","ignoreExpression","typeNarrowed"],"mappings":"uUAWC,wCAXuC,mBAAAA,cAWvCA,EAWA,SAAAC,eAAAC,EAAAF,GAAA,EAAAG,EAAAC,GAKE,IAAA,iCAAA,IAAAA,8BAEAD,+FAQF,wFAIWE,aAAAH,EAASF,KAAAG,UAMrB,KAHCH,oBAAAE,EAAAF"}
1
+ {"version":3,"file":"index.umd.production.min.cjs","sources":["../src/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"],"names":["expression","actual","expected","operator"],"mappings":";;;;;0EAaWA;;;;;MAuDRC;MAEAC,UAACF;MAGUG,UAAA;;;;;;;;;"}
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "ts-type-predicates",
3
- "version": "1.0.9",
4
- "description": "use asserts for make type predicates work",
3
+ "version": "1.0.12",
4
+ "description": "使用斷言(assert)讓類型斷言(type predicates)運作的實用工具函式 | Use asserts to make type predicates work with better runtime validation",
5
5
  "keywords": [
6
6
  ".d.ts",
7
7
  "@types",
8
+ "assert",
9
+ "asserts",
10
+ "assertion-function",
8
11
  "declaration",
9
12
  "dev",
10
13
  "develop",
@@ -17,7 +20,10 @@
17
20
  "runtime",
18
21
  "ts",
19
22
  "type",
23
+ "type-assertion",
20
24
  "type-level",
25
+ "type-narrowing",
26
+ "type-predicates",
21
27
  "typelevel",
22
28
  "types",
23
29
  "typescript",
@@ -43,8 +49,8 @@
43
49
  "exports": {
44
50
  ".": {
45
51
  "types": "./dist/index.d.ts",
46
- "import": "./dist/index.esm.mjs",
47
- "require": "./dist/index.cjs"
52
+ "require": "./dist/index.cjs",
53
+ "import": "./dist/index.esm.mjs"
48
54
  },
49
55
  "./package.json": "./package.json"
50
56
  },
@@ -56,17 +62,22 @@
56
62
  "test": "test"
57
63
  },
58
64
  "scripts": {
65
+ "coverage": "yarn run test -- --coverage",
59
66
  "lint": "ynpx --quiet eslint -- **/*.ts",
60
- "test": "echo \"Error: no test specified\"",
67
+ "test": "jest --passWithNoTests",
61
68
  "test:jest": "ynpx --quiet jest -- --coverage",
69
+ "test:jest:coverage": "node --run test:jest -- --coverage",
62
70
  "test:jest:snapshot": "yarn run test:jest -- -u",
63
71
  "test:mocha": "ynpx --quiet -p ts-node -p mocha mocha -- --require ts-node/register \"!(node_modules)/**/*.{test,spec}.{ts,tsx}\"",
64
72
  "test:snapshot": "yarn run test -- -u",
65
73
  "test:tsd": "ynpx tsd",
66
74
  "posttest": "yarn run build",
67
- "build": "yarn run build:tsdx && yarn run build:dts",
75
+ "build": "yarn run build:tsdx && yarn run build:dts:tsc",
68
76
  "build:dts": "ynpx dts-bundle-generator -o ./dist/index.d.ts ./src/index.ts --no-banner & echo build:dts",
69
- "build:tsdx": "ynpx @bluelovers/tsdx build --target node --name index",
77
+ "build:tsdx": "tsdx build --target node --name index",
78
+ "build:dts:copy": "copy .\\src\\index.d.ts .\\dist\\index.d.ts & echo build:dts",
79
+ "build:dts:tsc": "yarn run build:dts:tsc:emit && yarn run build:dts:copy",
80
+ "build:dts:tsc:emit": "tsc --emitDeclarationOnly --declaration --noEmit false",
70
81
  "preversion": "echo preversion && yarn run test",
71
82
  "version": "echo version",
72
83
  "postversion": "echo postversion",
@@ -82,6 +93,8 @@
82
93
  "sort-package-json": "ynpx --quiet yarn-tool -- sort",
83
94
  "tsc:showConfig": "ynpx get-current-tsconfig -p"
84
95
  },
85
- "packageManager": "yarn@^1.22.11",
86
- "gitHead": "fa34eea119b9bcbb363061ddffcfe9d78c2d0ddd"
96
+ "devDependencies": {
97
+ "@types/node": "^25.5.0"
98
+ },
99
+ "gitHead": "c87f657dc8050a9b9c3ed646262f6c497a867f05"
87
100
  }
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAAA,mCAAwC;AAExC,SAAgB,iBAAiB,CAAa,MAAa,EAAE,aAAiD,IAAI;IAEjH,UAAU,aAAV,UAAU,cAAV,UAAU,IAAV,UAAU,GAAK,IAAI,EAAC;IAEpB,IAAI,OAAO,UAAU,KAAK,UAAU,EACpC;QACC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;KAClC;IAED,OAAO,UAAU,CAAA;AAClB,CAAC;AAVD,8CAUC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAa,MAAa,EAAE,aAAkD,IAAI,EAAE,OAAgB,EAAE,gBAA0B;IAE7J,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEnD,IAAI,UAAU,KAAK,IAAI,IAAI,gBAAgB,KAAK,IAAI,EACpD;QACC,MAAM,IAAI,uBAAc,CAAC;YACxB,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,UAAU,MAAM,kBAAkB;YACtD,MAAM;YACN,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,gBAAgB;SAC1B,CAAC,CAAA;KACF;AACF,CAAC;AAbD,wCAaC;AAED,SAAgB,YAAY,CAAa,MAAa,EAAE,aAAkD,IAAI,EAAE,OAAgB;IAE/H,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEnD,IAAI,UAAU,KAAK,IAAI,EACvB;QACC,UAAU,GAAG,KAAK,CAAC;KACnB;IAED,OAAO,UAAU,CAAA;AAClB,CAAC;AAVD,oCAUC;AAED,kBAAe,cAAc,CAAC","sourcesContent":["import { AssertionError } from 'assert';\n\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * use asserts for make type predicates work\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n}\n\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;AAWA,8CAUC;AAsCD,wCAgBC;AAqBD,oCAUC;AA1GD,8BAA8B;AAC9B,mCAAwC;AAExC;;;;;;;GAOG;AACH,SAAgB,iBAAiB,CAAa,MAAa,EAAE,aAAiD,IAAI;IAEjH,UAAU,aAAV,UAAU,cAAV,UAAU,IAAV,UAAU,GAAK,IAAI,EAAC;IAEpB,IAAI,OAAO,UAAU,KAAK,UAAU,EACpC,CAAC;QACA,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,UAAU,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,SAAgB,cAAc,CAAa,MAAa,EAAE,aAAkD,IAAI,EAAE,OAAgB,EAAE,gBAA0B;IAE7J,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEnD,IAAI,UAAU,KAAK,IAAI,IAAI,gBAAgB,KAAK,IAAI,EACpD,CAAC;QACA,MAAM,IAAI,uBAAc,CAAC;YACxB,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,UAAU,MAAM,kBAAkB;YACtD,MAAM;YACN,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,gBAAgB;SAC1B,CAAC,CAAA;IACH,CAAC;IAED,aAAa;IACb,OAAO,UAAU,CAAA;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,YAAY,CAAa,MAAa,EAAE,aAAkD,IAAI,EAAE,OAAgB;IAE/H,UAAU,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAEnD,IAAI,UAAU,KAAK,IAAI,EACvB,CAAC;QACA,UAAU,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,UAAU,CAAA;AAClB,CAAC;AAED,kBAAe,cAAc,CAAC","sourcesContent":["/// <reference types=\"node\" />\nimport { AssertionError } from 'assert';\n\n/**\n * 處理表達式,回傳布林值結果\n * Handle expression and return boolean result\n *\n * @param actual - 實際值 / Actual value\n * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function\n * @returns 布林值結果 / Boolean result\n */\nexport function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)\n{\n\texpression ??= true;\n\n\tif (typeof expression === 'function')\n\t{\n\t\texpression = !!expression(actual);\n\t}\n\n\treturn expression\n}\n\n/**\n * 使用斷言(assert)讓類型斷言(type predicates)運作\n * Use asserts for make type predicates work\n *\n * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,\n * 允許在運行時驗證類型並在編譯時縮小類型範圍\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)\n * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false\n *\n * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates\n * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions\n *\n * @example\n * // 基本用法:失敗時拋出錯誤\n * typePredicates<string>(value, typeof value === 'string');\n *\n * @example\n * // 參數除了第一個以外都能省略\n * typePredicates<string>(value);\n *\n * @example\n * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)\n * if (typePredicates<string>(data.value, data.type === 'a')) {\n * // data.value 現在正確收窄為 string\n * console.log(data.value.toUpperCase());\n * }\n *\n * @example\n * // 忽略表達式結果,只做類型收窄,不拋出錯誤\n * typePredicates<string>(value, typeof value === 'string', undefined, true);\n */\nexport function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true && ignoreExpression !== true)\n\t{\n\t\tthrow new AssertionError({\n\t\t\tmessage: message ?? `actual ${actual} not as expected`,\n\t\t\tactual,\n\t\t\texpected: expression,\n\t\t\toperator: 'typePredicates',\n\t\t})\n\t}\n\n\t// @ts-ignore\n\treturn expression\n}\n\n/**\n * 類型收窄函式,回傳類型斷言結果\n * Type narrowing function, returns type predicate result\n *\n * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型\n * 可用於需要條件邏輯而非斷言的場景\n *\n * @param T - 預期的類型 / Expected type\n * @param actual - 實際值 / Actual value\n * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)\n * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)\n * @returns 是否符合預期類型 / Whether it matches the expected type\n *\n * @example\n * // 使用 typeNarrowed - 回傳布林值\n * if (typeNarrowed<string>(value, typeof value === 'string')) {\n * console.log(value.length);\n * }\n */\nexport function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T\n{\n\texpression = _handleExpression(actual, expression);\n\n\tif (expression !== true)\n\t{\n\t\texpression = false;\n\t}\n\n\treturn expression\n}\n\nexport default typePredicates;\n"]}
package/src/index.ts CHANGED
@@ -1,5 +1,14 @@
1
+ /// <reference types="node" />
1
2
  import { AssertionError } from 'assert';
2
3
 
4
+ /**
5
+ * 處理表達式,回傳布林值結果
6
+ * Handle expression and return boolean result
7
+ *
8
+ * @param actual - 實際值 / Actual value
9
+ * @param expression - 表達式,可為布林值或函式 / Expression, can be boolean or function
10
+ * @returns 布林值結果 / Boolean result
11
+ */
3
12
  export function _handleExpression<T, P = any>(actual: T | P, expression: boolean | ((actual: T | P) => any) = true)
4
13
  {
5
14
  expression ??= true;
@@ -13,10 +22,40 @@ export function _handleExpression<T, P = any>(actual: T | P, expression: boolean
13
22
  }
14
23
 
15
24
  /**
16
- * use asserts for make type predicates work
25
+ * 使用斷言(assert)讓類型斷言(type predicates)運作
26
+ * Use asserts for make type predicates work
27
+ *
28
+ * 此函式結合了 TypeScript 的斷言函式與類型斷言功能,
29
+ * 允許在運行時驗證類型並在編譯時縮小類型範圍
30
+ *
31
+ * @param T - 預期的類型 / Expected type
32
+ * @param actual - 實際值 / Actual value
33
+ * @param expression - 斷言條件,可為布林值或函式(可選)/ Assertion condition, can be boolean or function (optional)
34
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
35
+ * @param ignoreExpression - 是否忽略表達式結果,設為 true 時只做類型收窄不拋出錯誤(可選)/ Whether to ignore expression result (optional)
36
+ * @throws 當表達式結果為 false 時拋出 AssertionError / Throws AssertionError when expression is false
17
37
  *
18
38
  * @see https://www.typescriptlang.org/docs/handbook/advanced-types.html#using-type-predicates
19
39
  * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
40
+ *
41
+ * @example
42
+ * // 基本用法:失敗時拋出錯誤
43
+ * typePredicates<string>(value, typeof value === 'string');
44
+ *
45
+ * @example
46
+ * // 參數除了第一個以外都能省略
47
+ * typePredicates<string>(value);
48
+ *
49
+ * @example
50
+ * // 使用於 if 條件中 - 強制類型收窄 (需要配合使用 @ts-ignore 註釋)
51
+ * if (typePredicates<string>(data.value, data.type === 'a')) {
52
+ * // data.value 現在正確收窄為 string
53
+ * console.log(data.value.toUpperCase());
54
+ * }
55
+ *
56
+ * @example
57
+ * // 忽略表達式結果,只做類型收窄,不拋出錯誤
58
+ * typePredicates<string>(value, typeof value === 'string', undefined, true);
20
59
  */
21
60
  export function typePredicates<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string, ignoreExpression?: boolean): asserts actual is T
22
61
  {
@@ -31,8 +70,30 @@ export function typePredicates<T, P = any>(actual: T | P, expression : boolean |
31
70
  operator: 'typePredicates',
32
71
  })
33
72
  }
73
+
74
+ // @ts-ignore
75
+ return expression
34
76
  }
35
77
 
78
+ /**
79
+ * 類型收窄函式,回傳類型斷言結果
80
+ * Type narrowing function, returns type predicate result
81
+ *
82
+ * 此函式不會拋出錯誤,而是回傳布林值表示是否符合預期類型
83
+ * 可用於需要條件邏輯而非斷言的場景
84
+ *
85
+ * @param T - 預期的類型 / Expected type
86
+ * @param actual - 實際值 / Actual value
87
+ * @param expression - 驗證條件,可為布林值或函式(可選)/ Validation condition, can be boolean or function (optional)
88
+ * @param message - 自訂錯誤訊息(可選)/ Custom error message (optional)
89
+ * @returns 是否符合預期類型 / Whether it matches the expected type
90
+ *
91
+ * @example
92
+ * // 使用 typeNarrowed - 回傳布林值
93
+ * if (typeNarrowed<string>(value, typeof value === 'string')) {
94
+ * console.log(value.length);
95
+ * }
96
+ */
36
97
  export function typeNarrowed<T, P = any>(actual: T | P, expression : boolean | ((actual: T | P) => any) = true, message?: string): actual is T
37
98
  {
38
99
  expression = _handleExpression(actual, expression);