ts-type 3.0.15 → 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 +25 -0
- package/lib/helper/string/string-composition.d.ts +115 -0
- package/lib/helper/string/string-composition.js +3 -0
- package/lib/helper/string/string-composition.js.map +1 -0
- package/lib/helper/string.d.ts +6 -1
- package/lib/helper/string.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/type/record/union.d.ts +187 -6
- package/lib/type/record/union.js +26 -23
- package/lib/type/record/union.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
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
|
+
|
|
6
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)
|
|
7
32
|
|
|
8
33
|
|
|
@@ -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 @@
|
|
|
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"]}
|
package/lib/helper/string.d.ts
CHANGED
|
@@ -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
|
|
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}`
|
package/lib/helper/string.js.map
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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,71 +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
|
-
*
|
|
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
|
-
*
|
|
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
|
+
*/
|
|
136
293
|
export type ITSUnionToOptional<T> = [T] extends [infer U] ? {
|
|
137
294
|
[K in ITSKeyOfUnion<U>]?: U extends Record<K, any> ? U[K] : never;
|
|
138
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
|
+
*/
|
|
139
320
|
export type ITSAnyOfUnion<T> = ITSUnionToOptional<T> & T;
|
package/lib/type/record/union.js
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
└─
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
└─
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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\tT,\r\n\tK extends ITSKeyOfUnion<T>\r\n> = false extends (\r\n\t\tT extends unknown\r\n\t\t\t? K extends keyof T\r\n\t\t\t\t? {} extends Pick<T, K>\r\n\t\t\t\t\t? false\r\n\t\t\t\t\t: true\r\n\t\t\t\t: false\r\n\t\t\t: never\r\n\t\t)\r\n\t? false\r\n\t: 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\t[K in ITSKeyOfUnion<T>]:\r\n\tITSIsRequiredInUnion<T, K> extends true\r\n\t\t? K\r\n\t\t: 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\tExclude<\r\n\t\tITSKeyOfUnion<T>,\r\n\t\tITSKeyOfUnionRequired<T>\r\n\t>;\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\tT,\r\n\tK extends ITSKeyOfUnion<T>\r\n> = Omit<ITSUnionFlat<T>, K>\r\n\t& {\r\n\t[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\tT,\r\n\tK extends ITSKeyOfUnion<T>\r\n> = Omit<ITSUnionFlat<T>, K>\r\n\t& {\r\n\t[P in K]-?: ITSValueOfUnion<T, P>;\r\n};\r\n\r\n// ----------------\r\n\r\nexport type ITSUnionToOptional<T> = [T] extends [infer U]\r\n\t? { [K in ITSKeyOfUnion<U>]?: U extends Record<K, any> ? U[K] : never }\r\n\t: never;\r\n\r\nexport type ITSAnyOfUnion<T> = ITSUnionToOptional<T> & T;\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.
|
|
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):
|
|
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.
|
|
98
|
+
"@ts-type/object-freeze": "^1.0.16"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
101
|
"ts-toolbelt": "^9.6.0"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "6411b1f4cf689345537ab348e19e7e7dfd3bdfef"
|
|
104
104
|
}
|