ts-type 3.0.14 → 3.0.16

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,41 @@
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
+ ## [3.0.16](https://github.com/bluelovers/ws-ts-type/compare/ts-type@3.0.15...ts-type@3.0.16) (2026-09-27)
7
+
8
+
9
+
10
+ ### ✨ Features
11
+
12
+ * **ts-type:** 新增字串字面量組合工具類型 ([f57467d](https://github.com/bluelovers/ws-ts-type/commit/f57467de62ed6b3404388e8a620d0e2c73a4aeb2))
13
+
14
+
15
+ ### 📚 Documentation
16
+
17
+ * **ts-type:** 重構聯集轉可選/必填類型的實作方式 ([27cbfb6](https://github.com/bluelovers/ws-ts-type/commit/27cbfb6886a85fc7be426189212828a6fc8baeb3))
18
+
19
+
20
+ ### 🛠 Build System
21
+
22
+ * **release:** publish ([988ac2f](https://github.com/bluelovers/ws-ts-type/commit/988ac2f81a6a0d2ad797c9874c2fd25e7987749b))
23
+
24
+
25
+ ### ♻️ Chores
26
+
27
+ * **package:** 更新發布後的 Git 提交訊息內容 ([2f37128](https://github.com/bluelovers/ws-ts-type/commit/2f3712864caea40047a04f72391ba92948b86ac1))
28
+
29
+
30
+
31
+ ## [3.0.15](https://github.com/bluelovers/ws-ts-type/compare/ts-type@3.0.14...ts-type@3.0.15) (2026-09-25)
32
+
33
+
34
+
35
+ ### ✨ Features
36
+
37
+ * **ts-type:** 新增聯集轉可選類型相關工具類型 ([28cdc58](https://github.com/bluelovers/ws-ts-type/commit/28cdc58f2553631d4f8367f5f1c981cdfec4c6ba))
38
+
39
+
40
+
6
41
  ## [3.0.14](https://github.com/bluelovers/ws-ts-type/compare/ts-type@3.0.13...ts-type@3.0.14) (2026-09-25)
7
42
 
8
43
 
@@ -0,0 +1,115 @@
1
+ import { ITSTemplateLiteralAllowedType, ITSToStringLiteral } from "../string";
2
+ /**
3
+ * 將字串字面量加上前綴,組合成新的字串字面量
4
+ * Combines a prefix with a name into a new string literal.
5
+ *
6
+ * 當 Name 為聯集時,結果會對應展開為聯集
7
+ * When Name is a union, the result expands to a union accordingly.
8
+ *
9
+ * @example
10
+ * type A = ITSStringLiteralPrefixed<"Up", "STR">;
11
+ * // type A = "UpSTR"
12
+ *
13
+ * @example
14
+ * type B = ITSStringLiteralPrefixed<"Up", "STR" | "INT">;
15
+ * // type B = "UpSTR" | "UpINT"
16
+ */
17
+ export type ITSStringLiteralPrefixed<Prefix extends ITSTemplateLiteralAllowedType, Name extends ITSTemplateLiteralAllowedType> = `${Prefix}${Name}`;
18
+ /**
19
+ * 將字串字面量加上後綴,組合成新的字串字面量
20
+ * Combines a name with a suffix into a new string literal.
21
+ *
22
+ * 當 Name 為聯集時,結果會對應展開為聯集
23
+ * When Name is a union, the result expands to a union accordingly.
24
+ *
25
+ * @example
26
+ * type A = ITSStringLiteralSuffixed<"STR", "Status">;
27
+ * // type A = "STRStatus"
28
+ *
29
+ * @example
30
+ * type B = ITSStringLiteralSuffixed<"STR" | "INT", "Status">;
31
+ * // type B = "STRStatus" | "INTStatus"
32
+ */
33
+ export type ITSStringLiteralSuffixed<Name extends ITSTemplateLiteralAllowedType, Suffix extends ITSTemplateLiteralAllowedType> = `${Name}${Suffix}`;
34
+ /**
35
+ * 以 Name 聯集的每個成員為鍵,建立其值為「前綴 + 鍵名」的對應記錄型別
36
+ * Builds a record whose keys are the members of the Name union and
37
+ * whose values are the prefixed string literal of each key.
38
+ *
39
+ * @example
40
+ * type T = ITSStringLiteralPrefixedRecord<"Up", "STR" | "INT" | "DEX">;
41
+ * // type T = {
42
+ * // STR: "UpSTR";
43
+ * // INT: "UpINT";
44
+ * // DEX: "UpDEX";
45
+ * // }
46
+ */
47
+ export type ITSStringLiteralPrefixedRecord<Prefix extends ITSTemplateLiteralAllowedType, Name extends ITSTemplateLiteralAllowedType> = {
48
+ [K in ITSToStringLiteral<Name>]: ITSStringLiteralPrefixed<Prefix, K>;
49
+ };
50
+ /**
51
+ * 以 Name 聯集的每個成員為鍵,建立其值為「鍵名 + 後綴」的對應記錄型別
52
+ * Builds a record whose keys are the members of the Name union and
53
+ * whose values are the suffixed string literal of each key.
54
+ *
55
+ * @example
56
+ * type T = ITSStringLiteralSuffixedRecord<"STR" | "INT", "Status">;
57
+ * // type T = {
58
+ * // STR: "STRStatus";
59
+ * // INT: "INTStatus";
60
+ * // }
61
+ */
62
+ export type ITSStringLiteralSuffixedRecord<Name extends ITSTemplateLiteralAllowedType, Suffix extends ITSTemplateLiteralAllowedType> = {
63
+ [K in ITSToStringLiteral<Name>]: ITSStringLiteralSuffixed<K, Suffix>;
64
+ };
65
+ /**
66
+ * 以 Name 聯集為基礎,透過 KeyMap 重新映射鍵名、並以 ValueMap 指定
67
+ * 對應的值型別,建立一組自訂的對應記錄型別
68
+ * Builds a custom mapped record from the Name union, remapping each
69
+ * key via KeyMap and assigning the value type from ValueMap.
70
+ *
71
+ * @example
72
+ * type Name = "STR" | "INT" | "DEX";
73
+ * type KeyMap = { STR: "str"; INT: "int"; DEX: "dex" };
74
+ * type ValueMap = { STR: number; INT: number; DEX: number };
75
+ *
76
+ * type T = ITSRecordMap<Name, KeyMap, ValueMap>;
77
+ * // type T = {
78
+ * // str: number;
79
+ * // int: number;
80
+ * // dex: number;
81
+ * // }
82
+ *
83
+ * @example
84
+ * 當 ValueMap 的值型別為 string 時:
85
+ * type Name = "STR" | "INT" | "DEX";
86
+ * type KeyMap = { STR: "str"; INT: "int"; DEX: "dex" };
87
+ * type ValueMap = { STR: string; INT: string; DEX: string };
88
+ *
89
+ * type T = ITSRecordMap<Name, KeyMap, ValueMap>;
90
+ * // type T = {
91
+ * // str: string;
92
+ * // int: string;
93
+ * // dex: string;
94
+ * // }
95
+ *
96
+ * @example
97
+ * 當 ValueMap 的值型別為物件型別時:
98
+ * type Name = "STR" | "INT" | "DEX";
99
+ * type KeyMap = { STR: "str"; INT: "int"; DEX: "dex" };
100
+ * type ValueMap = {
101
+ * STR: { label: string; value: number };
102
+ * INT: { label: string; value: number };
103
+ * DEX: { label: string; value: number };
104
+ * };
105
+ *
106
+ * type T = ITSRecordMap<Name, KeyMap, ValueMap>;
107
+ * // type T = {
108
+ * // str: { label: string; value: number };
109
+ * // int: { label: string; value: number };
110
+ * // dex: { label: string; value: number };
111
+ * // }
112
+ */
113
+ export type ITSRecordMap<Name extends ITSTemplateLiteralAllowedType, KeyMap extends Record<ITSToStringLiteral<Name>, PropertyKey>, ValueMap extends Record<ITSToStringLiteral<Name>, unknown>> = {
114
+ [K in ITSToStringLiteral<Name> as KeyMap[K]]: ValueMap[K];
115
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=string-composition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-composition.js","sourceRoot":"","sources":["string-composition.ts"],"names":[],"mappings":"","sourcesContent":["/*\n * 字串字面量組合工具\n * String Literal Composition Utilities\n *\n * 以 EnumStatusAttr(枚舉狀態屬性)為例的組合流程 / composition flow:\n *\n * EnumStatusAttr\n * │\n * ├──────────────┐\n * │ │\n * ▼ ▼\n * Name Union PrefixedRecord\n * │ │\n * │ └── STR → UpSTR\n * │ INT → UpINT\n * │ DEX → UpDEX\n * │\n * ▼\n * PrefixedUnion\n * │\n * └── 'UpSTR' | 'UpINT' | 'UpDEX' | ...\n */\nimport { ITSTemplateLiteralAllowedType, ITSToStringLiteral } from \"../string\";\n\n/**\n * 將字串字面量加上前綴,組合成新的字串字面量\n * Combines a prefix with a name into a new string literal.\n *\n * 當 Name 為聯集時,結果會對應展開為聯集\n * When Name is a union, the result expands to a union accordingly.\n *\n * @example\n * type A = ITSStringLiteralPrefixed<\"Up\", \"STR\">;\n * // type A = \"UpSTR\"\n *\n * @example\n * type B = ITSStringLiteralPrefixed<\"Up\", \"STR\" | \"INT\">;\n * // type B = \"UpSTR\" | \"UpINT\"\n */\nexport type ITSStringLiteralPrefixed<\n\tPrefix extends ITSTemplateLiteralAllowedType,\n\tName extends ITSTemplateLiteralAllowedType,\n> = `${Prefix}${Name}`;\n\n/**\n * 將字串字面量加上後綴,組合成新的字串字面量\n * Combines a name with a suffix into a new string literal.\n *\n * 當 Name 為聯集時,結果會對應展開為聯集\n * When Name is a union, the result expands to a union accordingly.\n *\n * @example\n * type A = ITSStringLiteralSuffixed<\"STR\", \"Status\">;\n * // type A = \"STRStatus\"\n *\n * @example\n * type B = ITSStringLiteralSuffixed<\"STR\" | \"INT\", \"Status\">;\n * // type B = \"STRStatus\" | \"INTStatus\"\n */\nexport type ITSStringLiteralSuffixed<\n\tName extends ITSTemplateLiteralAllowedType,\n\tSuffix extends ITSTemplateLiteralAllowedType,\n> = `${Name}${Suffix}`;\n\n/**\n * 以 Name 聯集的每個成員為鍵,建立其值為「前綴 + 鍵名」的對應記錄型別\n * Builds a record whose keys are the members of the Name union and\n * whose values are the prefixed string literal of each key.\n *\n * @example\n * type T = ITSStringLiteralPrefixedRecord<\"Up\", \"STR\" | \"INT\" | \"DEX\">;\n * // type T = {\n * // STR: \"UpSTR\";\n * // INT: \"UpINT\";\n * // DEX: \"UpDEX\";\n * // }\n */\nexport type ITSStringLiteralPrefixedRecord<\n\tPrefix extends ITSTemplateLiteralAllowedType,\n\tName extends ITSTemplateLiteralAllowedType,\n> = {\n\t[K in ITSToStringLiteral<Name>]:\n\t\tITSStringLiteralPrefixed<Prefix, K>;\n};\n\n/**\n * 以 Name 聯集的每個成員為鍵,建立其值為「鍵名 + 後綴」的對應記錄型別\n * Builds a record whose keys are the members of the Name union and\n * whose values are the suffixed string literal of each key.\n *\n * @example\n * type T = ITSStringLiteralSuffixedRecord<\"STR\" | \"INT\", \"Status\">;\n * // type T = {\n * // STR: \"STRStatus\";\n * // INT: \"INTStatus\";\n * // }\n */\nexport type ITSStringLiteralSuffixedRecord<\n\tName extends ITSTemplateLiteralAllowedType,\n\tSuffix extends ITSTemplateLiteralAllowedType,\n> = {\n\t[K in ITSToStringLiteral<Name>]:\n\t\tITSStringLiteralSuffixed<K, Suffix>;\n};\n\n/**\n * 以 Name 聯集為基礎,透過 KeyMap 重新映射鍵名、並以 ValueMap 指定\n * 對應的值型別,建立一組自訂的對應記錄型別\n * Builds a custom mapped record from the Name union, remapping each\n * key via KeyMap and assigning the value type from ValueMap.\n *\n * @example\n * type Name = \"STR\" | \"INT\" | \"DEX\";\n * type KeyMap = { STR: \"str\"; INT: \"int\"; DEX: \"dex\" };\n * type ValueMap = { STR: number; INT: number; DEX: number };\n *\n * type T = ITSRecordMap<Name, KeyMap, ValueMap>;\n * // type T = {\n * // str: number;\n * // int: number;\n * // dex: number;\n * // }\n *\n * @example\n * 當 ValueMap 的值型別為 string 時:\n * type Name = \"STR\" | \"INT\" | \"DEX\";\n * type KeyMap = { STR: \"str\"; INT: \"int\"; DEX: \"dex\" };\n * type ValueMap = { STR: string; INT: string; DEX: string };\n *\n * type T = ITSRecordMap<Name, KeyMap, ValueMap>;\n * // type T = {\n * // str: string;\n * // int: string;\n * // dex: string;\n * // }\n *\n * @example\n * 當 ValueMap 的值型別為物件型別時:\n * type Name = \"STR\" | \"INT\" | \"DEX\";\n * type KeyMap = { STR: \"str\"; INT: \"int\"; DEX: \"dex\" };\n * type ValueMap = {\n * STR: { label: string; value: number };\n * INT: { label: string; value: number };\n * DEX: { label: string; value: number };\n * };\n *\n * type T = ITSRecordMap<Name, KeyMap, ValueMap>;\n * // type T = {\n * // str: { label: string; value: number };\n * // int: { label: string; value: number };\n * // dex: { label: string; value: number };\n * // }\n */\nexport type ITSRecordMap<\n\tName extends ITSTemplateLiteralAllowedType,\n\tKeyMap extends Record<ITSToStringLiteral<Name>, PropertyKey>,\n\tValueMap extends Record<ITSToStringLiteral<Name>, unknown>,\n> = {\n\t[K in ITSToStringLiteral<Name> as KeyMap[K]]:\n\t\tValueMap[K];\n};\n"]}
@@ -6,7 +6,12 @@
6
6
  * Provides utilities for converting strings, numbers, booleans to literal types
7
7
  */
8
8
  /** 允許轉換為字面量類型的基礎類型 / Base types allowed to convert to literal types */
9
- export type ITSToStringLiteralAllowedType = string | number | boolean | bigint;
9
+ export type ITSTemplateLiteralAllowedType = string | number | boolean | bigint;
10
+ /**
11
+ * @alias {@link ITSTemplateLiteralAllowedType}
12
+ * @deprecated Use {@link ITSTemplateLiteralAllowedType} instead
13
+ */
14
+ export type ITSToStringLiteralAllowedType = ITSTemplateLiteralAllowedType;
10
15
  /**
11
16
  * 將類型轉換為字面量類型 `${T}`
12
17
  * Convert type to literal type `${T}`
@@ -1 +1 @@
1
- {"version":3,"file":"string.js","sourceRoot":"","sources":["string.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * 字面量類型工具\n * Literal Type Utilities\n *\n * 提供字串、數字、布林值轉換為字面量類型的工具\n * Provides utilities for converting strings, numbers, booleans to literal types\n */\n\n/** 允許轉換為字面量類型的基礎類型 / Base types allowed to convert to literal types */\nexport type ITSToStringLiteralAllowedType = string | number | boolean | bigint;\n\n/**\n * 將類型轉換為字面量類型 `${T}`\n * Convert type to literal type `${T}`\n *\n * @example\n * type Str = ITSToStringLiteral<'hello'>;\n * // type Str = \"hello\"\n *\n * @example\n * type Num = ITSToStringLiteral<42>;\n * // type Num = \"42\"\n */\nexport type ITSToStringLiteral<T extends ITSToStringLiteralAllowedType> = `${T}`\n\n/**\n * 原始類型與其字面量類型的聯合\n * Union of original type and its literal type\n *\n * T & `${T}`\n *\n * 適合用在 enum 或 string literal union,可以接受 enum 的字面量或基底類型\n * Suitable for enum or string literal union, can accept enum literal or base type\n *\n * @example\n * // 應用於 string literal union\n * type Status = 'active' | 'inactive' | 'pending';\n * type IStatus = ITSTypeAndStringLiteral<Status>;\n * // type IStatus = \"active\" | \"inactive\" | \"pending\" | string\n *\n * @example\n * // 應用於 enum\n * enum EnumPackageManager {\n * 'yarn' = 'yarn',\n * 'npm' = 'npm',\n * 'pnpm' = 'pnpm',\n * }\n * type IPackageManager = ITSTypeAndStringLiteral<EnumPackageManager>;\n * // type IPackageManager = EnumPackageManager | string\n *\n * @example\n * // 應用於 number,可接受數字或數字字串\n * type INumber = ITSTypeAndStringLiteral<number>;\n * // type INumber = number | `${number}`\n */\nexport type ITSTypeAndStringLiteral<T extends ITSToStringLiteralAllowedType> = T | ITSToStringLiteral<T>\n\n/**\n * 原始類型 S 與 T 的字面量類型的聯合\n * Union of original type S and literal type of T\n *\n * S & `${T}`\n *\n * @example\n * type Result = ITSAndStringLiteral<1 | 2 | 3, number>;\n * // type Result = number | \"1\" | \"2\" | \"3\"\n */\nexport type ITSAndStringLiteral<T extends ITSToStringLiteralAllowedType, S = string> = S | ITSToStringLiteral<T>\n\n/**\n * 原始類型 S、T 與 T 的字面量類型的聯合\n * Union of original types S, T and literal type of T\n *\n * S & T & `${T}`\n *\n * @example\n * type Result = ITSAndTypeAndStringLiteral<1 | 2 | 3, number>;\n * // type Result = number | \"1\" | \"2\" | \"3\"\n */\nexport type ITSAndTypeAndStringLiteral<T extends ITSToStringLiteralAllowedType, S = string> =\n\tS\n\t| ITSTypeAndStringLiteral<T>\n"]}
1
+ {"version":3,"file":"string.js","sourceRoot":"","sources":["string.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG","sourcesContent":["/**\n * 字面量類型工具\n * Literal Type Utilities\n *\n * 提供字串、數字、布林值轉換為字面量類型的工具\n * Provides utilities for converting strings, numbers, booleans to literal types\n */\n\n/** 允許轉換為字面量類型的基礎類型 / Base types allowed to convert to literal types */\nexport type ITSTemplateLiteralAllowedType = string | number | boolean | bigint;\n\n/**\n * @alias {@link ITSTemplateLiteralAllowedType}\n * @deprecated Use {@link ITSTemplateLiteralAllowedType} instead\n */\nexport type ITSToStringLiteralAllowedType = ITSTemplateLiteralAllowedType;\n\n/**\n * 將類型轉換為字面量類型 `${T}`\n * Convert type to literal type `${T}`\n *\n * @example\n * type Str = ITSToStringLiteral<'hello'>;\n * // type Str = \"hello\"\n *\n * @example\n * type Num = ITSToStringLiteral<42>;\n * // type Num = \"42\"\n */\nexport type ITSToStringLiteral<T extends ITSToStringLiteralAllowedType> = `${T}`\n\n/**\n * 原始類型與其字面量類型的聯合\n * Union of original type and its literal type\n *\n * T & `${T}`\n *\n * 適合用在 enum 或 string literal union,可以接受 enum 的字面量或基底類型\n * Suitable for enum or string literal union, can accept enum literal or base type\n *\n * @example\n * // 應用於 string literal union\n * type Status = 'active' | 'inactive' | 'pending';\n * type IStatus = ITSTypeAndStringLiteral<Status>;\n * // type IStatus = \"active\" | \"inactive\" | \"pending\" | string\n *\n * @example\n * // 應用於 enum\n * enum EnumPackageManager {\n * 'yarn' = 'yarn',\n * 'npm' = 'npm',\n * 'pnpm' = 'pnpm',\n * }\n * type IPackageManager = ITSTypeAndStringLiteral<EnumPackageManager>;\n * // type IPackageManager = EnumPackageManager | string\n *\n * @example\n * // 應用於 number,可接受數字或數字字串\n * type INumber = ITSTypeAndStringLiteral<number>;\n * // type INumber = number | `${number}`\n */\nexport type ITSTypeAndStringLiteral<T extends ITSToStringLiteralAllowedType> = T | ITSToStringLiteral<T>\n\n/**\n * 原始類型 S 與 T 的字面量類型的聯合\n * Union of original type S and literal type of T\n *\n * S & `${T}`\n *\n * @example\n * type Result = ITSAndStringLiteral<1 | 2 | 3, number>;\n * // type Result = number | \"1\" | \"2\" | \"3\"\n */\nexport type ITSAndStringLiteral<T extends ITSToStringLiteralAllowedType, S = string> = S | ITSToStringLiteral<T>\n\n/**\n * 原始類型 S、T 與 T 的字面量類型的聯合\n * Union of original types S, T and literal type of T\n *\n * S & T & `${T}`\n *\n * @example\n * type Result = ITSAndTypeAndStringLiteral<1 | 2 | 3, number>;\n * // type Result = number | \"1\" | \"2\" | \"3\"\n */\nexport type ITSAndTypeAndStringLiteral<T extends ITSToStringLiteralAllowedType, S = string> =\n\tS\n\t| ITSTypeAndStringLiteral<T>\n"]}
package/lib/index.d.ts CHANGED
@@ -22,6 +22,7 @@ export * from './helper/string';
22
22
  export * from './helper/string/infer';
23
23
  export * from './helper/string/literal-string';
24
24
  export * from './helper/string/operations';
25
+ export * from './helper/string/string-composition';
25
26
  export * from './helper/tuple';
26
27
  export * from './helper/typeof';
27
28
  export * from './internal/filter';
@@ -1,10 +1,14 @@
1
1
  import { ITSKeyOfUnion, ITSValueOfUnion } from "../../helper/key-value";
2
2
  import { ITSPartialPick, ITSRequiredPick } from "../record";
3
3
  /**
4
+ * 在保留每個聯集成員結構的前提下,將選取的屬性設為可選
4
5
  * Makes the selected properties optional while preserving
5
6
  * the structure of each union member.
6
7
  *
7
- * This is the distributive Union version.
8
+ * 這是分配式 (distributive) 的 Union 版本,會對聯集的每個成員
9
+ * 分別套用 `Partial<Pick<T, K>>`
10
+ * This is the distributive Union version: it applies
11
+ * `Partial<Pick<T, K>>` to each union member individually.
8
12
  *
9
13
  * @example
10
14
  * type T =
@@ -24,10 +28,14 @@ export type ITSPartialPickUnion<T, K extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>
24
28
  [P in K & keyof T]?: T[P];
25
29
  } : never;
26
30
  /**
31
+ * 在保留每個聯集成員結構的前提下,將選取的屬性設為必填
27
32
  * Makes the selected properties required while preserving
28
33
  * the structure of each union member.
29
34
  *
30
- * This is the distributive Union version.
35
+ * 這是分配式 (distributive) 的 Union 版本,會對聯集的每個成員
36
+ * 分別套用 `Required<Pick<T, K>>`
37
+ * This is the distributive Union version: it applies
38
+ * `Required<Pick<T, K>>` to each union member individually.
31
39
  *
32
40
  * @example
33
41
  * type T =
@@ -47,11 +55,15 @@ export type ITSRequiredPickUnion<T, K extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T
47
55
  [P in K & keyof T]-?: T[P];
48
56
  } : never;
49
57
  /**
58
+ * 將選取的屬性設為可選,並把聯集中所有成員的屬性扁平化為單一物件型別
50
59
  * Makes the selected properties optional and flattens
51
60
  * all properties from every union member into a single object type.
52
61
  *
62
+ * 與 ITSPartialPickUnion 不同,此工具不保留各聯集成員的個別結構,
63
+ * 而是將所有鍵合併到同一個物件中
53
64
  * Unlike ITSPartialPickUnion, this does not preserve the
54
- * individual union-member structure.
65
+ * individual union-member structure; instead it merges all keys
66
+ * into a single object.
55
67
  *
56
68
  * @example
57
69
  * type T =
@@ -69,67 +81,240 @@ export type ITSPartialPickUnionFlat<T, K extends ITSKeyOfUnion<T> = ITSKeyOfUnio
69
81
  [P in K]?: ITSValueOfUnion<T, P>;
70
82
  };
71
83
  /**
84
+ * 將選取的屬性設為必填,並把聯集中所有成員扁平化為單一物件型別
72
85
  * Makes the selected properties required and flattens
73
86
  * all members of a union into a single object type.
74
87
  *
88
+ * 注意:此工具會刻意將所有選取的屬性設為必填。若需要更自然地保留
89
+ * 「屬性是否於每個成員中都存在」的語意,請改用 ITSUnionFlat 等
90
+ * 以扁平化為基礎的工具。
75
91
  * Note: this utility intentionally makes every selected property
76
92
  * required. For a natural flattened representation that preserves
77
93
  * whether a property exists in every member, use a dedicated
78
- * flat-base utility.
94
+ * flat-base utility such as ITSUnionFlat.
95
+ *
96
+ * @example
97
+ * type T =
98
+ * | { type: "a"; value: number }
99
+ * | { type: "b"; text: string };
100
+ *
101
+ * type Result = ITSRequiredPickUnionFlat<T>;
102
+ * // {
103
+ * // type: "a" | "b";
104
+ * // value: number;
105
+ * // text: string;
106
+ * // }
79
107
  */
80
108
  export type ITSRequiredPickUnionFlat<T, K extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>> = {
81
109
  [P in K]-?: ITSValueOfUnion<T, P>;
82
110
  };
83
111
  /**
112
+ * 在保留聯集成員結構的前提下,將指定屬性設為必填
84
113
  * Makes the specified properties required for each member
85
114
  * of a union while preserving the union-member structure.
86
115
  *
116
+ * 其餘屬性保持不變(未被選取的屬性原樣保留)
87
117
  * Other properties are preserved unchanged.
118
+ *
119
+ * @example
120
+ * type T =
121
+ * | { type: "a"; value?: number }
122
+ * | { type: "b"; text?: string };
123
+ *
124
+ * type Result = ITSRequiredWithUnion<T, "value" | "text">;
125
+ * // {
126
+ * // type: "a";
127
+ * // value: number;
128
+ * // } | {
129
+ * // type: "b";
130
+ * // text: string;
131
+ * // }
88
132
  */
89
133
  export type ITSRequiredWithUnion<T, K extends ITSKeyOfUnion<T>> = T extends any ? K extends keyof T ? Omit<T, K> & ITSRequiredPick<T, K> : T : never;
90
134
  /**
135
+ * 在保留聯集成員結構的前提下,將指定屬性設為可選
91
136
  * Makes the specified properties optional for each member
92
137
  * of a union while preserving the union-member structure.
93
138
  *
139
+ * 其餘屬性保持不變(未被選取的屬性原樣保留)
94
140
  * Other properties are preserved unchanged.
141
+ *
142
+ * @example
143
+ * type T =
144
+ * | { type: "a"; value: number }
145
+ * | { type: "b"; text: string };
146
+ *
147
+ * type Result = ITSPartialWithUnion<T, "value" | "text">;
148
+ * // {
149
+ * // type: "a";
150
+ * // value?: number;
151
+ * // } | {
152
+ * // type: "b";
153
+ * // text?: string;
154
+ * // }
95
155
  */
96
156
  export type ITSPartialWithUnion<T, K extends ITSKeyOfUnion<T>> = T extends any ? K extends keyof T ? Omit<T, K> & ITSPartialPick<T, K> : T : never;
157
+ /**
158
+ * 將聯集扁平化為單一物件型別,並依各屬性在聯集中的存在情況
159
+ * 決定其為必填或可選
160
+ * Flattens a union into a single object type, marking each
161
+ * property as required or optional based on whether it exists
162
+ * in every union member.
163
+ *
164
+ * 在每個成員都必填的鍵會被設為必填;否則設為可選
165
+ * Keys required in every member become required; the rest optional.
166
+ *
167
+ * @example
168
+ * type T =
169
+ * | { type: "a"; value: number }
170
+ * | { type: "b"; value?: string };
171
+ *
172
+ * type Result = ITSUnionFlat<T>;
173
+ * // {
174
+ * // type: "a" | "b";
175
+ * // value?: number | string;
176
+ * // }
177
+ */
97
178
  export type ITSUnionFlat<T> = {
98
179
  [P in ITSKeyOfUnionRequired<T>]-?: ITSValueOfUnion<T, P>;
99
180
  } & {
100
181
  [P in ITSKeyOfUnionOptional<T>]?: ITSValueOfUnion<T, P>;
101
182
  };
102
183
  /**
184
+ * 判斷鍵 K 是否在聯集 T 的每個成員中都為必填
103
185
  * Checks whether K is required in every member of T.
186
+ *
187
+ * @example
188
+ * type T =
189
+ * | { type: "a"; value: number }
190
+ * | { type: "b"; value?: string };
191
+ *
192
+ * type A = ITSIsRequiredInUnion<T, "type">; // true
193
+ * type B = ITSIsRequiredInUnion<T, "value">; // false
104
194
  */
105
195
  export type ITSIsRequiredInUnion<T, K extends ITSKeyOfUnion<T>> = false extends (T extends unknown ? K extends keyof T ? {} extends Pick<T, K> ? false : true : false : never) ? false : true;
106
196
  /**
197
+ * 取得在聯集 T 每個成員中都為必填的鍵集合
107
198
  * Gets keys that are required in every member of T.
199
+ *
200
+ * @example
201
+ * type T =
202
+ * | { type: "a"; value: number }
203
+ * | { type: "b"; value?: string };
204
+ *
205
+ * type RequiredKeys = ITSKeyOfUnionRequired<T>;
206
+ * // "type"
108
207
  */
109
208
  export type ITSKeyOfUnionRequired<T> = {
110
209
  [K in ITSKeyOfUnion<T>]: ITSIsRequiredInUnion<T, K> extends true ? K : never;
111
210
  }[ITSKeyOfUnion<T>];
112
211
  /**
212
+ * 取得在聯集 T 中並非於每個成員都必填的鍵集合
113
213
  * Gets keys that are not required in every member of T.
214
+ *
215
+ * @example
216
+ * type T =
217
+ * | { type: "a"; value: number }
218
+ * | { type: "b"; value?: string };
219
+ *
220
+ * type OptionalKeys = ITSKeyOfUnionOptional<T>;
221
+ * // "value"
114
222
  */
115
223
  export type ITSKeyOfUnionOptional<T> = Exclude<ITSKeyOfUnion<T>, ITSKeyOfUnionRequired<T>>;
116
224
  /**
117
- * Makes the specified properties required and flattens
225
+ * 將聯集扁平化為單一物件型別,並將指定屬性設為可選
226
+ * Makes the specified properties optional and flattens
118
227
  * all members of a union into a single object type.
119
228
  *
229
+ * 其餘來自各聯集成員的屬性會以可選屬性保留,因為它們不一定
230
+ * 存在於每個成員之中
120
231
  * Other properties from all union members are preserved as
121
232
  * optional properties because they may not exist in every member.
233
+ *
234
+ * @example
235
+ * type T =
236
+ * | { type: "a"; value: number }
237
+ * | { type: "b"; value?: string };
238
+ *
239
+ * type Result = ITSPartialWithUnionFlat<T, "value">;
240
+ * // {
241
+ * // type?: "a" | "b";
242
+ * // value?: number | string;
243
+ * // }
122
244
  */
123
245
  export type ITSPartialWithUnionFlat<T, K extends ITSKeyOfUnion<T>> = Omit<ITSUnionFlat<T>, K> & {
124
246
  [P in K]?: ITSValueOfUnion<T, P>;
125
247
  };
126
248
  /**
127
- * Makes the specified properties optional and flattens
249
+ * 將聯集扁平化為單一物件型別,並將指定屬性設為必填
250
+ * Makes the specified properties required and flattens
128
251
  * all members of a union into a single object type.
129
252
  *
253
+ * 其餘來自各聯集成員的屬性會以可選屬性保留,因為它們不一定
254
+ * 存在於每個成員之中
130
255
  * Other properties from all union members are preserved as
131
256
  * optional properties because they may not exist in every member.
257
+ *
258
+ * @example
259
+ * type T =
260
+ * | { type: "a"; value: number }
261
+ * | { type: "b"; value?: string };
262
+ *
263
+ * type Result = ITSRequiredWithUnionFlat<T, "value">;
264
+ * // {
265
+ * // type?: "a" | "b";
266
+ * // value: number | string;
267
+ * // }
132
268
  */
133
269
  export type ITSRequiredWithUnionFlat<T, K extends ITSKeyOfUnion<T>> = Omit<ITSUnionFlat<T>, K> & {
134
270
  [P in K]-?: ITSValueOfUnion<T, P>;
135
271
  };
272
+ /**
273
+ * 將聯集 T 扁平化為單一物件型別,並把所有鍵設為可選
274
+ * Flattens a union T into a single object type and makes
275
+ * all keys optional.
276
+ *
277
+ * 僅保留那些在成員中存在、且型別為該成員對應屬性類型的屬性
278
+ * Only members that actually contain the key contribute their
279
+ * property type.
280
+ *
281
+ * @example
282
+ * type T =
283
+ * | { type: "a"; value: number }
284
+ * | { type: "b"; text: string };
285
+ *
286
+ * type Result = ITSUnionToOptional<T>;
287
+ * // {
288
+ * // type?: "a" | "b";
289
+ * // value?: number;
290
+ * // text?: string;
291
+ * // }
292
+ */
293
+ export type ITSUnionToOptional<T> = [T] extends [infer U] ? {
294
+ [K in ITSKeyOfUnion<U>]?: U extends Record<K, any> ? U[K] : never;
295
+ } : never;
296
+ /**
297
+ * 取得聯集 T 在「所有鍵皆為可選」版本與原聯集型別的交集
298
+ * Gets the intersection of T with its all-optional flattened form.
299
+ *
300
+ * 可同時接受「完全可選」的物件,也能精確匹配原本的聯集成員
301
+ * Accepts a fully-optional object while still matching the
302
+ * original union members exactly.
303
+ *
304
+ * @example
305
+ * type T =
306
+ * | { type: "a"; value: number }
307
+ * | { type: "b"; text: string };
308
+ *
309
+ * type Result = ITSAnyOfUnion<T>;
310
+ * // {
311
+ * // type?: "a" | "b";
312
+ * // value?: number;
313
+ * // text?: string;
314
+ * // } & ({
315
+ * // type: "a"; value: number;
316
+ * // } | {
317
+ * // type: "b"; text: string;
318
+ * // })
319
+ */
320
+ export type ITSAnyOfUnion<T> = ITSUnionToOptional<T> & T;
@@ -1,27 +1,30 @@
1
1
  "use strict";
2
2
  /*
3
- ITSPartialPick / ITSRequiredPick
4
- └─ 一般 Object
5
- └─ keyof T
6
-
7
- ITSPartialPickUnion / ITSRequiredPickUnion
8
- └─ Union
9
- └─ 保留 A | B 結構
10
- └─ distributive conditional type
11
-
12
- ITSPartialPickUnionFlat / ITSRequiredPickUnionFlat
13
- └─ UnionFlat
14
- └─ A | B → 單一 Object
15
- └─ ITSKeyOfUnion + ITSValueOfUnion
16
-
17
- PartialWith
18
- → 修改 K,保留 Object
19
-
20
- PartialWithUnion
21
- → 修改 K,保留 A | B
22
-
23
- PartialWithUnionFlat
24
- → Flatten A | B,再只修改 K
25
- */
3
+ * 聯集 (Union) 型別的鍵選取工具總覽
4
+ * Overview of Union key-selection utilities
5
+ *
6
+ * ITSPartialPick / ITSRequiredPick
7
+ * └─ 一般 Object / 一般物件
8
+ * └─ keyof T
9
+ *
10
+ * ITSPartialPickUnion / ITSRequiredPickUnion
11
+ * └─ Union 聯集
12
+ * └─ 保留 A | B 結構 / preserve A | B structure
13
+ * └─ distributive conditional type / 分配式條件型別
14
+ *
15
+ * ITSPartialPickUnionFlat / ITSRequiredPickUnionFlat
16
+ * └─ UnionFlat 扁平聯集
17
+ * └─ A | B → 單一 Object / A | B → single object
18
+ * └─ ITSKeyOfUnion + ITSValueOfUnion
19
+ *
20
+ * PartialWith
21
+ * → 修改 K,保留 Object / modify K, preserve object
22
+ *
23
+ * PartialWithUnion
24
+ * → 修改 K,保留 A | B / modify K, preserve A | B
25
+ *
26
+ * PartialWithUnionFlat
27
+ * → Flatten A | B,再只修改 K / flatten A | B, then modify only K
28
+ */
26
29
  Object.defineProperty(exports, "__esModule", { value: true });
27
30
  //# sourceMappingURL=union.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"union.js","sourceRoot":"","sources":["union.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;EAuBE","sourcesContent":["/*\r\nITSPartialPick / ITSRequiredPick\r\n└─ 一般 Object\r\n └─ keyof T\r\n\r\nITSPartialPickUnion / ITSRequiredPickUnion\r\n└─ Union\r\n └─ 保留 A | B 結構\r\n └─ distributive conditional type\r\n\r\nITSPartialPickUnionFlat / ITSRequiredPickUnionFlat\r\n└─ UnionFlat\r\n └─ A | B → 單一 Object\r\n └─ ITSKeyOfUnion + ITSValueOfUnion\r\n\r\nPartialWith\r\n\t→ 修改 K,保留 Object\r\n\r\nPartialWithUnion\r\n\t→ 修改 K,保留 A | B\r\n\r\nPartialWithUnionFlat\r\n\t→ Flatten A | B,再只修改 K\r\n*/\r\n\r\nimport { ITSKeyOfUnion, ITSValueOfUnion } from \"../../helper/key-value\";\r\nimport { ITSPartialPick, ITSPartialWith, ITSRequiredPick, ITSRequiredWith } from \"../record\";\r\n\r\n/**\r\n * Makes the selected properties optional while preserving\r\n * the structure of each union member.\r\n *\r\n * This is the distributive Union version.\r\n *\r\n * @example\r\n * type T =\r\n * | { type: \"a\"; value: number }\r\n * | { type: \"b\"; text: string };\r\n *\r\n * type Result = ITSPartialPickUnion<T>;\r\n * // {\r\n * // type?: \"a\";\r\n * // value?: number;\r\n * // } | {\r\n * // type?: \"b\";\r\n * // text?: string;\r\n * // }\r\n */\r\nexport type ITSPartialPickUnion<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\r\n> = T extends any\r\n\t? {\r\n\t\t[P in K & keyof T]?: T[P];\r\n\t}\r\n\t: never;\r\n\r\n/**\r\n * Makes the selected properties required while preserving\r\n * the structure of each union member.\r\n *\r\n * This is the distributive Union version.\r\n *\r\n * @example\r\n * type T =\r\n * | { type: \"a\"; value?: number }\r\n * | { type: \"b\"; text?: string };\r\n *\r\n * type Result = ITSRequiredPickUnion<T>;\r\n * // {\r\n * // type: \"a\";\r\n * // value: number;\r\n * // } | {\r\n * // type: \"b\";\r\n * // text: string;\r\n * // }\r\n */\r\nexport type ITSRequiredPickUnion<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\r\n> = T extends any\r\n\t? {\r\n\t\t[P in K & keyof T]-?: T[P];\r\n\t}\r\n\t: never;\r\n\r\n/**\r\n * Makes the selected properties optional and flattens\r\n * all properties from every union member into a single object type.\r\n *\r\n * Unlike ITSPartialPickUnion, this does not preserve the\r\n * individual union-member structure.\r\n *\r\n * @example\r\n * type T =\r\n * | { type: \"a\"; value: number }\r\n * | { type: \"b\"; text: string };\r\n *\r\n * type Result = ITSPartialPickUnionFlat<T>;\r\n * // {\r\n * // type?: \"a\" | \"b\";\r\n * // value?: number;\r\n * // text?: string;\r\n * // }\r\n */\r\nexport type ITSPartialPickUnionFlat<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\r\n> = {\r\n\t[P in K]?: ITSValueOfUnion<T, P>;\r\n};\r\n\r\n/**\r\n * Makes the selected properties required and flattens\r\n * all members of a union into a single object type.\r\n *\r\n * Note: this utility intentionally makes every selected property\r\n * required. For a natural flattened representation that preserves\r\n * whether a property exists in every member, use a dedicated\r\n * flat-base utility.\r\n */\r\nexport type ITSRequiredPickUnionFlat<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\r\n> = {\r\n\t[P in K]-?: ITSValueOfUnion<T, P>;\r\n};\r\n\r\n// ---------------\r\n\r\n/**\r\n * Makes the specified properties required for each member\r\n * of a union while preserving the union-member structure.\r\n *\r\n * Other properties are preserved unchanged.\r\n */\r\nexport type ITSRequiredWithUnion<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T>\r\n> = T extends any\r\n\t? K extends keyof T\r\n\t\t? Omit<T, K> & ITSRequiredPick<T, K>\r\n\t\t: T\r\n\t: never;\r\n\r\n/**\r\n * Makes the specified properties optional for each member\r\n * of a union while preserving the union-member structure.\r\n *\r\n * Other properties are preserved unchanged.\r\n */\r\nexport type ITSPartialWithUnion<\r\n\tT,\r\n\tK extends ITSKeyOfUnion<T>\r\n> = T extends any\r\n\t? K extends keyof T\r\n\t\t? Omit<T, K> & ITSPartialPick<T, K>\r\n\t\t: T\r\n\t: never;\r\n\r\nexport type ITSUnionFlat<T> = {\r\n\t[P in ITSKeyOfUnionRequired<T>]-?: ITSValueOfUnion<T, P>;\r\n} & {\r\n\t[P in ITSKeyOfUnionOptional<T>]?: ITSValueOfUnion<T, P>;\r\n};\r\n\r\n/**\r\n * Checks whether K is required in every member of T.\r\n */\r\nexport type ITSIsRequiredInUnion<\r\n T,\r\n K extends ITSKeyOfUnion<T>\r\n> = false extends (\r\n T extends unknown\r\n ? K extends keyof T\r\n ? {} extends Pick<T, K>\r\n ? false\r\n : true\r\n : false\r\n : never\r\n)\r\n ? false\r\n : true;\r\n\r\n/**\r\n * Gets keys that are required in every member of T.\r\n */\r\nexport type ITSKeyOfUnionRequired<T> = {\r\n [K in ITSKeyOfUnion<T>]:\r\n ITSIsRequiredInUnion<T, K> extends true\r\n ? K\r\n : never;\r\n}[ITSKeyOfUnion<T>];\r\n\r\n/**\r\n * Gets keys that are not required in every member of T.\r\n */\r\nexport type ITSKeyOfUnionOptional<T> =\r\n Exclude<\r\n ITSKeyOfUnion<T>,\r\n ITSKeyOfUnionRequired<T>\r\n >;\r\n\r\n/**\r\n * Makes the specified properties required and flattens\r\n * all members of a union into a single object type.\r\n *\r\n * Other properties from all union members are preserved as\r\n * optional properties because they may not exist in every member.\r\n */\r\nexport type ITSPartialWithUnionFlat<\r\n T,\r\n K extends ITSKeyOfUnion<T>\r\n> = Omit<ITSUnionFlat<T>, K>\r\n & {\r\n [P in K]?: ITSValueOfUnion<T, P>;\r\n };\r\n\r\n/**\r\n * Makes the specified properties optional and flattens\r\n * all members of a union into a single object type.\r\n *\r\n * Other properties from all union members are preserved as\r\n * optional properties because they may not exist in every member.\r\n */\r\nexport type ITSRequiredWithUnionFlat<\r\n T,\r\n K extends ITSKeyOfUnion<T>\r\n> = Omit<ITSUnionFlat<T>, K>\r\n & {\r\n [P in K]-?: ITSValueOfUnion<T, P>;\r\n };"]}
1
+ {"version":3,"file":"union.js","sourceRoot":"","sources":["union.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG","sourcesContent":["/*\n * 聯集 (Union) 型別的鍵選取工具總覽\n * Overview of Union key-selection utilities\n *\n * ITSPartialPick / ITSRequiredPick\n * └─ 一般 Object / 一般物件\n * └─ keyof T\n *\n * ITSPartialPickUnion / ITSRequiredPickUnion\n * └─ Union 聯集\n * └─ 保留 A | B 結構 / preserve A | B structure\n * └─ distributive conditional type / 分配式條件型別\n *\n * ITSPartialPickUnionFlat / ITSRequiredPickUnionFlat\n * └─ UnionFlat 扁平聯集\n * └─ A | B → 單一 Object / A | B → single object\n * └─ ITSKeyOfUnion + ITSValueOfUnion\n *\n * PartialWith\n * \t→ 修改 K,保留 Object / modify K, preserve object\n *\n * PartialWithUnion\n * \t→ 修改 K,保留 A | B / modify K, preserve A | B\n *\n * PartialWithUnionFlat\n * \t→ Flatten A | B,再只修改 K / flatten A | B, then modify only K\n */\n\nimport { ITSKeyOfUnion, ITSValueOfUnion } from \"../../helper/key-value\";\nimport { ITSPartialPick, ITSPartialWith, ITSRequiredPick, ITSRequiredWith } from \"../record\";\n\n/**\n * 在保留每個聯集成員結構的前提下,將選取的屬性設為可選\n * Makes the selected properties optional while preserving\n * the structure of each union member.\n *\n * 這是分配式 (distributive) 的 Union 版本,會對聯集的每個成員\n * 分別套用 `Partial<Pick<T, K>>`\n * This is the distributive Union version: it applies\n * `Partial<Pick<T, K>>` to each union member individually.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSPartialPickUnion<T>;\n * // {\n * // type?: \"a\";\n * // value?: number;\n * // } | {\n * // type?: \"b\";\n * // text?: string;\n * // }\n */\nexport type ITSPartialPickUnion<\n\tT,\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\n> = T extends any\n\t? {\n\t\t[P in K & keyof T]?: T[P];\n\t}\n\t: never;\n\n/**\n * 在保留每個聯集成員結構的前提下,將選取的屬性設為必填\n * Makes the selected properties required while preserving\n * the structure of each union member.\n *\n * 這是分配式 (distributive) 的 Union 版本,會對聯集的每個成員\n * 分別套用 `Required<Pick<T, K>>`\n * This is the distributive Union version: it applies\n * `Required<Pick<T, K>>` to each union member individually.\n *\n * @example\n * type T =\n * | { type: \"a\"; value?: number }\n * | { type: \"b\"; text?: string };\n *\n * type Result = ITSRequiredPickUnion<T>;\n * // {\n * // type: \"a\";\n * // value: number;\n * // } | {\n * // type: \"b\";\n * // text: string;\n * // }\n */\nexport type ITSRequiredPickUnion<\n\tT,\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\n> = T extends any\n\t? {\n\t\t[P in K & keyof T]-?: T[P];\n\t}\n\t: never;\n\n/**\n * 將選取的屬性設為可選,並把聯集中所有成員的屬性扁平化為單一物件型別\n * Makes the selected properties optional and flattens\n * all properties from every union member into a single object type.\n *\n * 與 ITSPartialPickUnion 不同,此工具不保留各聯集成員的個別結構,\n * 而是將所有鍵合併到同一個物件中\n * Unlike ITSPartialPickUnion, this does not preserve the\n * individual union-member structure; instead it merges all keys\n * into a single object.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSPartialPickUnionFlat<T>;\n * // {\n * // type?: \"a\" | \"b\";\n * // value?: number;\n * // text?: string;\n * // }\n */\nexport type ITSPartialPickUnionFlat<\n\tT,\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\n> = {\n\t[P in K]?: ITSValueOfUnion<T, P>;\n};\n\n/**\n * 將選取的屬性設為必填,並把聯集中所有成員扁平化為單一物件型別\n * Makes the selected properties required and flattens\n * all members of a union into a single object type.\n *\n * 注意:此工具會刻意將所有選取的屬性設為必填。若需要更自然地保留\n * 「屬性是否於每個成員中都存在」的語意,請改用 ITSUnionFlat 等\n * 以扁平化為基礎的工具。\n * Note: this utility intentionally makes every selected property\n * required. For a natural flattened representation that preserves\n * whether a property exists in every member, use a dedicated\n * flat-base utility such as ITSUnionFlat.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSRequiredPickUnionFlat<T>;\n * // {\n * // type: \"a\" | \"b\";\n * // value: number;\n * // text: string;\n * // }\n */\nexport type ITSRequiredPickUnionFlat<\n\tT,\n\tK extends ITSKeyOfUnion<T> = ITSKeyOfUnion<T>\n> = {\n\t[P in K]-?: ITSValueOfUnion<T, P>;\n};\n\n// ---------------\n\n/**\n * 在保留聯集成員結構的前提下,將指定屬性設為必填\n * Makes the specified properties required for each member\n * of a union while preserving the union-member structure.\n *\n * 其餘屬性保持不變(未被選取的屬性原樣保留)\n * Other properties are preserved unchanged.\n *\n * @example\n * type T =\n * | { type: \"a\"; value?: number }\n * | { type: \"b\"; text?: string };\n *\n * type Result = ITSRequiredWithUnion<T, \"value\" | \"text\">;\n * // {\n * // type: \"a\";\n * // value: number;\n * // } | {\n * // type: \"b\";\n * // text: string;\n * // }\n */\nexport type ITSRequiredWithUnion<\n\tT,\n\tK extends ITSKeyOfUnion<T>\n> = T extends any\n\t? K extends keyof T\n\t\t? Omit<T, K> & ITSRequiredPick<T, K>\n\t\t: T\n\t: never;\n\n/**\n * 在保留聯集成員結構的前提下,將指定屬性設為可選\n * Makes the specified properties optional for each member\n * of a union while preserving the union-member structure.\n *\n * 其餘屬性保持不變(未被選取的屬性原樣保留)\n * Other properties are preserved unchanged.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSPartialWithUnion<T, \"value\" | \"text\">;\n * // {\n * // type: \"a\";\n * // value?: number;\n * // } | {\n * // type: \"b\";\n * // text?: string;\n * // }\n */\nexport type ITSPartialWithUnion<\n\tT,\n\tK extends ITSKeyOfUnion<T>\n> = T extends any\n\t? K extends keyof T\n\t\t? Omit<T, K> & ITSPartialPick<T, K>\n\t\t: T\n\t: never;\n\n/**\n * 將聯集扁平化為單一物件型別,並依各屬性在聯集中的存在情況\n * 決定其為必填或可選\n * Flattens a union into a single object type, marking each\n * property as required or optional based on whether it exists\n * in every union member.\n *\n * 在每個成員都必填的鍵會被設為必填;否則設為可選\n * Keys required in every member become required; the rest optional.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type Result = ITSUnionFlat<T>;\n * // {\n * // type: \"a\" | \"b\";\n * // value?: number | string;\n * // }\n */\nexport type ITSUnionFlat<T> = {\n\t[P in ITSKeyOfUnionRequired<T>]-?: ITSValueOfUnion<T, P>;\n} & {\n\t[P in ITSKeyOfUnionOptional<T>]?: ITSValueOfUnion<T, P>;\n};\n\n/**\n * 判斷鍵 K 是否在聯集 T 的每個成員中都為必填\n * Checks whether K is required in every member of T.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type A = ITSIsRequiredInUnion<T, \"type\">; // true\n * type B = ITSIsRequiredInUnion<T, \"value\">; // false\n */\nexport type ITSIsRequiredInUnion<\n\tT,\n\tK extends ITSKeyOfUnion<T>\n> = false extends (\n\tT extends unknown\n\t\t? K extends keyof T\n\t\t\t? {} extends Pick<T, K>\n\t\t\t\t? false\n\t\t\t\t: true\n\t\t\t: false\n\t\t: never\n\t)\n\t? false\n\t: true;\n\n/**\n * 取得在聯集 T 每個成員中都為必填的鍵集合\n * Gets keys that are required in every member of T.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type RequiredKeys = ITSKeyOfUnionRequired<T>;\n * // \"type\"\n */\nexport type ITSKeyOfUnionRequired<T> = {\n\t[K in ITSKeyOfUnion<T>]:\n\tITSIsRequiredInUnion<T, K> extends true\n\t\t? K\n\t\t: never;\n}[ITSKeyOfUnion<T>];\n\n/**\n * 取得在聯集 T 中並非於每個成員都必填的鍵集合\n * Gets keys that are not required in every member of T.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type OptionalKeys = ITSKeyOfUnionOptional<T>;\n * // \"value\"\n */\nexport type ITSKeyOfUnionOptional<T> =\n\tExclude<\n\t\tITSKeyOfUnion<T>,\n\t\tITSKeyOfUnionRequired<T>\n\t>;\n\n/**\n * 將聯集扁平化為單一物件型別,並將指定屬性設為可選\n * Makes the specified properties optional and flattens\n * all members of a union into a single object type.\n *\n * 其餘來自各聯集成員的屬性會以可選屬性保留,因為它們不一定\n * 存在於每個成員之中\n * Other properties from all union members are preserved as\n * optional properties because they may not exist in every member.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type Result = ITSPartialWithUnionFlat<T, \"value\">;\n * // {\n * // type?: \"a\" | \"b\";\n * // value?: number | string;\n * // }\n */\nexport type ITSPartialWithUnionFlat<\n\tT,\n\tK extends ITSKeyOfUnion<T>\n> = Omit<ITSUnionFlat<T>, K>\n\t& {\n\t[P in K]?: ITSValueOfUnion<T, P>;\n};\n\n/**\n * 將聯集扁平化為單一物件型別,並將指定屬性設為必填\n * Makes the specified properties required and flattens\n * all members of a union into a single object type.\n *\n * 其餘來自各聯集成員的屬性會以可選屬性保留,因為它們不一定\n * 存在於每個成員之中\n * Other properties from all union members are preserved as\n * optional properties because they may not exist in every member.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; value?: string };\n *\n * type Result = ITSRequiredWithUnionFlat<T, \"value\">;\n * // {\n * // type?: \"a\" | \"b\";\n * // value: number | string;\n * // }\n */\nexport type ITSRequiredWithUnionFlat<\n\tT,\n\tK extends ITSKeyOfUnion<T>\n> = Omit<ITSUnionFlat<T>, K>\n\t& {\n\t[P in K]-?: ITSValueOfUnion<T, P>;\n};\n\n// ----------------\n\n/**\n * 將聯集 T 扁平化為單一物件型別,並把所有鍵設為可選\n * Flattens a union T into a single object type and makes\n * all keys optional.\n *\n * 僅保留那些在成員中存在、且型別為該成員對應屬性類型的屬性\n * Only members that actually contain the key contribute their\n * property type.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSUnionToOptional<T>;\n * // {\n * // type?: \"a\" | \"b\";\n * // value?: number;\n * // text?: string;\n * // }\n */\nexport type ITSUnionToOptional<T> = [T] extends [infer U]\n\t? { [K in ITSKeyOfUnion<U>]?: U extends Record<K, any> ? U[K] : never }\n\t: never;\n\n/**\n * 取得聯集 T 在「所有鍵皆為可選」版本與原聯集型別的交集\n * Gets the intersection of T with its all-optional flattened form.\n *\n * 可同時接受「完全可選」的物件,也能精確匹配原本的聯集成員\n * Accepts a fully-optional object while still matching the\n * original union members exactly.\n *\n * @example\n * type T =\n * | { type: \"a\"; value: number }\n * | { type: \"b\"; text: string };\n *\n * type Result = ITSAnyOfUnion<T>;\n * // {\n * // type?: \"a\" | \"b\";\n * // value?: number;\n * // text?: string;\n * // } & ({\n * // type: \"a\"; value: number;\n * // } | {\n * // type: \"b\"; text: string;\n * // })\n */\nexport type ITSAnyOfUnion<T> = ITSUnionToOptional<T> & T;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-type",
3
- "version": "3.0.14",
3
+ "version": "3.0.16",
4
4
  "description": "TypeScript 類型工具庫:提供豐富的類型操作工具和重新導出的內建類型 / TypeScript type utility library: provides rich type manipulation utilities and re-exported built-in types",
5
5
  "keywords": [
6
6
  ".d.ts",
@@ -69,7 +69,7 @@
69
69
  "build:toc": "tsc --skipLibCheck & echo build:toc",
70
70
  "preversion": "pnpm run test && pnpm run postpublish:git:commit",
71
71
  "prepublishOnly": "echo prepublishOnly",
72
- "postpublish:git:commit": "git commit -m \"build(release): publish\" ./lib/index.d.ts ./lib & echo postpublish:git:commit",
72
+ "postpublish:git:commit": "git commit -m \"build(release): update generated files\" ./lib/index.d.ts ./lib & echo postpublish:git:commit",
73
73
  "ncu": "yarn-tool ncu -u",
74
74
  "sort-package-json": "yarn-tool sort",
75
75
  "ts:check": "tsc -p tsconfig.check.json --emitDeclarationOnly --skipLibCheck",
@@ -95,10 +95,10 @@
95
95
  "typedarray-dts": "^1.0.0"
96
96
  },
97
97
  "devDependencies": {
98
- "@ts-type/object-freeze": "^1.0.14"
98
+ "@ts-type/object-freeze": "^1.0.16"
99
99
  },
100
100
  "peerDependencies": {
101
101
  "ts-toolbelt": "^9.6.0"
102
102
  },
103
- "gitHead": "673857cff12964d50e2da0224bd21fcf06c7744b"
103
+ "gitHead": "6411b1f4cf689345537ab348e19e7e7dfd3bdfef"
104
104
  }