@zwa73/utils 1.0.202 → 1.0.204
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/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/package.json +7 -4
- package/compile.bat +0 -2
- package/dist/UtilFfmpegTools.d.ts +0 -86
- package/dist/UtilFfmpegTools.js +0 -291
- package/input.wav +0 -0
- package/jest.config.js +0 -16
- package/scripts/compile.ps1 +0 -6
- package/scripts/expand-macro.ps1 +0 -2
- package/scripts/postinstall.js +0 -61
- package/scripts/release.ps1 +0 -3
- package/scripts/watch.ps1 +0 -10
- package/src/QuickExport.ts +0 -70
- package/src/UtilClass.ts +0 -259
- package/src/UtilCodecs.ts +0 -102
- package/src/UtilCom.macro.ts +0 -28
- package/src/UtilCom.ts +0 -456
- package/src/UtilCom_bak.txt +0 -345
- package/src/UtilDecorators.ts +0 -223
- package/src/UtilFP.macro.ts +0 -29
- package/src/UtilFP.ts +0 -222
- package/src/UtilFfmpegTools.ts +0 -320
- package/src/UtilFileTools.ts +0 -410
- package/src/UtilFunctions.ts +0 -938
- package/src/UtilI18n.ts +0 -278
- package/src/UtilInterfaces.ts +0 -264
- package/src/UtilLogger.ts +0 -390
- package/src/UtilSymbol.ts +0 -45
- package/src/backup.txt +0 -102
- package/src/index.ts +0 -13
- package/test.bat +0 -2
- package/watch.bat +0 -1
package/src/UtilI18n.ts
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import { UtilFT } from "./UtilFileTools";
|
|
2
|
-
import { UtilFunc } from "./UtilFunctions";
|
|
3
|
-
import { PRecord } from "./UtilInterfaces";
|
|
4
|
-
import { SLogger } from "./UtilLogger";
|
|
5
|
-
import path from 'pathe';
|
|
6
|
-
|
|
7
|
-
/**语言:地区 表 */
|
|
8
|
-
const I18nFlagTable = {
|
|
9
|
-
"zh":["CN","TW"],
|
|
10
|
-
"en":["US"]
|
|
11
|
-
} as const;
|
|
12
|
-
|
|
13
|
-
/**语言标签 */
|
|
14
|
-
export type LangFlag = {
|
|
15
|
-
[P in keyof typeof I18nFlagTable]: `${P}-${typeof I18nFlagTable[P][number]}`
|
|
16
|
-
}[keyof typeof I18nFlagTable]|keyof typeof I18nFlagTable;
|
|
17
|
-
|
|
18
|
-
/**语言标签列表 */
|
|
19
|
-
const LangFlagList = Object.entries(I18nFlagTable)
|
|
20
|
-
.map(([k,v])=>`${k}-${v}` as LangFlag)
|
|
21
|
-
.concat(Object.keys(I18nFlagTable) as LangFlag[]);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
/**源语言文本数据 */
|
|
26
|
-
export type I18nOrigTextData = {
|
|
27
|
-
/**原文 */
|
|
28
|
-
original:string;
|
|
29
|
-
/**出现位置 */
|
|
30
|
-
position?:string;
|
|
31
|
-
/**特殊说明 */
|
|
32
|
-
desc?:string;
|
|
33
|
-
/**无效的 默认false */
|
|
34
|
-
invalid?:boolean;
|
|
35
|
-
/**特殊标记 */
|
|
36
|
-
mark?:string;
|
|
37
|
-
/**抓取时间戳 */
|
|
38
|
-
scan_time:string;
|
|
39
|
-
/**抓取方式 */
|
|
40
|
-
source:'Regex'|'Ast'|'Runtime'|'Manual'
|
|
41
|
-
};
|
|
42
|
-
/**I18n源语言数据 */
|
|
43
|
-
export type I18nOrigTable = {
|
|
44
|
-
/**基础语言 */
|
|
45
|
-
base_lang:LangFlag;
|
|
46
|
-
texts:I18nOrigTextData[]
|
|
47
|
-
}
|
|
48
|
-
/**单语言I18N数据 */
|
|
49
|
-
export type I18nSingleTable = {
|
|
50
|
-
/**基础语言 */
|
|
51
|
-
base_lang:LangFlag;
|
|
52
|
-
/**目标语言 */
|
|
53
|
-
target_lang:LangFlag;
|
|
54
|
-
/**更改时间戳 */
|
|
55
|
-
modify_time:string;
|
|
56
|
-
/**文本翻译表 */
|
|
57
|
-
translate_table:Record<string,string|null>;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
/**处理过的i18n文本数据 */
|
|
62
|
-
export type I18nTextData = I18nOrigTextData&{lang_table:PRecord<LangFlag,string>};
|
|
63
|
-
/**处理过的I18n数据 */
|
|
64
|
-
export type I18nTable = Omit<I18nOrigTable,'texts'>&{
|
|
65
|
-
text_table:Record<string,I18nTextData>;
|
|
66
|
-
}
|
|
67
|
-
const parseLangFlag = (lf:LangFlag|'*')=>{
|
|
68
|
-
const match = lf.match(/^([^-]+)(.+)/)!
|
|
69
|
-
return {1:match[1],2:match[2]!='' ? match[2]:undefined};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const MarkRegex = /%([^%]+)%$/;
|
|
73
|
-
const BaseFile = 'base_lang.json';
|
|
74
|
-
const TemplateFile = 'template.json';
|
|
75
|
-
const LangDir = 'lang';
|
|
76
|
-
/**运行时I18n工具
|
|
77
|
-
* 需先调用 init初始化
|
|
78
|
-
*/
|
|
79
|
-
export class SI18n {
|
|
80
|
-
private static _table?:I18nTable;
|
|
81
|
-
private static _lang?:LangFlag;
|
|
82
|
-
private static _dataDir?:string;
|
|
83
|
-
private static _vaildLang?:(LangFlag|'template')[];
|
|
84
|
-
/**解析i18n索引 */
|
|
85
|
-
static parseI18nKey(i18nKey:string){
|
|
86
|
-
const match = i18nKey.match(/([\s\S]+?)((?<!\\)%[^%]+(?<!\\)%$)?$/)!;
|
|
87
|
-
const base = match[1];
|
|
88
|
-
const mark = match[2]==''||match[2]==undefined
|
|
89
|
-
? undefined
|
|
90
|
-
: match[2].match(/^%([^%]+)%$/)![1];
|
|
91
|
-
return {base,mark};
|
|
92
|
-
}
|
|
93
|
-
/**格式化文本与mark为i18n索引key */
|
|
94
|
-
static formatI18nKey(str:string,mark?:string){
|
|
95
|
-
return str + (mark==undefined ? '' : SI18n.mark(mark));
|
|
96
|
-
}
|
|
97
|
-
/**特殊标记
|
|
98
|
-
* 若添加在文本末尾则不会作为原文文本显示, 仅供索引
|
|
99
|
-
* @param mk - 特殊标记文本
|
|
100
|
-
*/
|
|
101
|
-
static mark(mk:string):`%${string}%`{
|
|
102
|
-
return `%${mk}%`
|
|
103
|
-
}
|
|
104
|
-
/**初始化函数,加载国际化数据,设置语言,并在进程退出前保存数据。
|
|
105
|
-
* @param i18nDataDir - 国际化数据的路径。
|
|
106
|
-
* @param lang - 要设置的语言。
|
|
107
|
-
*/
|
|
108
|
-
static async init(i18nDataDir:string,lang:LangFlag|'*'='*'){
|
|
109
|
-
const date = new Date().toISOString();
|
|
110
|
-
const mergePath = path.join(i18nDataDir,BaseFile);
|
|
111
|
-
const table = await UtilFT.loadJSONFile<I18nOrigTable>(mergePath,{default:{
|
|
112
|
-
base_lang:'zh-CN',
|
|
113
|
-
texts:[],
|
|
114
|
-
}});
|
|
115
|
-
const {texts,...rest} = table;
|
|
116
|
-
SI18n._table={
|
|
117
|
-
...rest,
|
|
118
|
-
text_table:texts.reduce((acc, cur) =>
|
|
119
|
-
({...acc,[SI18n.formatI18nKey(cur.original,cur.mark)]:{...cur,lang_table:{}}}),
|
|
120
|
-
{} as Record<string,I18nTextData>),
|
|
121
|
-
}
|
|
122
|
-
SI18n._vaildLang=['template'];
|
|
123
|
-
//覆盖入单语言文件
|
|
124
|
-
const singleDir = path.join(i18nDataDir,LangDir);
|
|
125
|
-
(await Promise.all((await UtilFT.fileSearchGlob(singleDir,`**/${parseLangFlag(lang)[1]}*.json`))
|
|
126
|
-
.map(async p=>await UtilFT.loadJSONFile(p) as I18nSingleTable)))
|
|
127
|
-
.forEach(t=>{
|
|
128
|
-
SI18n._vaildLang?.push(t.target_lang);
|
|
129
|
-
return Object.entries(t.translate_table)
|
|
130
|
-
.forEach(([k,v])=>{
|
|
131
|
-
if(v==null) return;
|
|
132
|
-
const ttable = SI18n._table!.text_table;
|
|
133
|
-
ttable[k] ??= {
|
|
134
|
-
original:k,
|
|
135
|
-
scan_time:date,
|
|
136
|
-
source:'Runtime',
|
|
137
|
-
lang_table:{}
|
|
138
|
-
}
|
|
139
|
-
const ltable = ttable[k].lang_table;
|
|
140
|
-
ltable[t.target_lang] ??= v;
|
|
141
|
-
})
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
if(lang!=undefined && lang!='*' && !SI18n._vaildLang.includes(lang))
|
|
145
|
-
SI18n._vaildLang.push(lang);
|
|
146
|
-
|
|
147
|
-
SI18n._lang = lang=="*" ? undefined : lang;
|
|
148
|
-
SI18n._dataDir = i18nDataDir;
|
|
149
|
-
}
|
|
150
|
-
/**根据提供的字符串,返回对应的国际化字符串
|
|
151
|
-
* @param text - 字符串数组
|
|
152
|
-
* @param markStr - 特殊标记文本
|
|
153
|
-
* @returns 对应的国际化字符串。
|
|
154
|
-
* @example
|
|
155
|
-
* t(`你好${v0}, ${v1}`,'hello3');
|
|
156
|
-
*/
|
|
157
|
-
static t(text:string,markStr:string):string;
|
|
158
|
-
/**根据提供的模板字符串和值,返回对应的国际化字符串。
|
|
159
|
-
* @param strings - 模板字符串数组。
|
|
160
|
-
* @param values - 值数组。
|
|
161
|
-
* @returns 对应的国际化字符串。
|
|
162
|
-
* @example
|
|
163
|
-
* t`你好${v0}, ${v1}${SI18n.mark('hello2')}`
|
|
164
|
-
*/
|
|
165
|
-
static t(strings:TemplateStringsArray,...values:any[]):string;
|
|
166
|
-
static t(strings:string|TemplateStringsArray,...values:any[]){
|
|
167
|
-
if(typeof strings =='string'){
|
|
168
|
-
const mark = values.length>=1 ? SI18n.mark(values[0]) : '';
|
|
169
|
-
return SI18n.getI18n(strings.replace(/%/g,'\\%')+mark, SI18n._lang!)
|
|
170
|
-
.replace(/\\%/g,'%');
|
|
171
|
-
}
|
|
172
|
-
let i18nKey = ``;
|
|
173
|
-
const vakyeKeys = values.map((v,i)=>`%${i}`);
|
|
174
|
-
for (let i = 0; i < values.length; i++)
|
|
175
|
-
i18nKey += strings[i].replace(/%/g,'\\%') + vakyeKeys[i];
|
|
176
|
-
i18nKey += strings[strings.length - 1];
|
|
177
|
-
|
|
178
|
-
//检查是否为mark
|
|
179
|
-
if(MarkRegex.test(String(values[values.length-1])) && strings[strings.length - 1]=='')
|
|
180
|
-
i18nKey = i18nKey.replace(vakyeKeys[vakyeKeys.length - 1],'') + String(values[values.length-1]);
|
|
181
|
-
//console.log(1,i18nKey)
|
|
182
|
-
let trans = SI18n.getI18n(i18nKey, SI18n._lang!);
|
|
183
|
-
//console.log(2,trans)
|
|
184
|
-
vakyeKeys.forEach((k,i)=>trans = trans.replace(new RegExp(
|
|
185
|
-
`((?<!\\\\)${k})`
|
|
186
|
-
),String(values[i])));
|
|
187
|
-
//console.log(3,trans)
|
|
188
|
-
return trans.replace(/\\%/g,'%');
|
|
189
|
-
}
|
|
190
|
-
/**根据提供的键和语言,返回对应的国际化字符串。
|
|
191
|
-
* 如果没有找到对应的字符串,将会抛出错误。
|
|
192
|
-
* @param key - 要查找的键。
|
|
193
|
-
* @param lang - 要查找的语言。
|
|
194
|
-
* @returns 对应的国际化字符串。
|
|
195
|
-
*/
|
|
196
|
-
static getI18n(key:string,lang?:LangFlag){
|
|
197
|
-
if(SI18n._table==undefined) UtilFunc.throwError('SI18n 未初始化');
|
|
198
|
-
let obj = SI18n._table.text_table[key];
|
|
199
|
-
if(obj==undefined){
|
|
200
|
-
SLogger.warn(`SI18n 未在 ${SI18n._dataDir} 找到 ${key} 对应的数据, 已自动添加`);
|
|
201
|
-
const p = SI18n.parseI18nKey(key);
|
|
202
|
-
obj = SI18n.addOriginalText({
|
|
203
|
-
original:p.base,
|
|
204
|
-
scan_time:new Date().toISOString(),
|
|
205
|
-
lang_table:{},
|
|
206
|
-
mark:p.mark,
|
|
207
|
-
source:'Runtime'
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
if(lang==undefined) return obj.original;
|
|
211
|
-
if(obj.invalid===true) return obj.original;
|
|
212
|
-
return SI18n.tryAndRollback(lang,obj);
|
|
213
|
-
}
|
|
214
|
-
/**尝试获取指定语言的翻译,如果没有找到,将回滚到其他可用的语言。
|
|
215
|
-
* @param lang - 要查找的语言。
|
|
216
|
-
* @param dat - 包含翻译的数据对象。
|
|
217
|
-
* @returns 找到的翻译,如果没有找到,将返回原始字符串。
|
|
218
|
-
*/
|
|
219
|
-
static tryAndRollback(lang:LangFlag,dat:I18nTable['text_table'][string]){
|
|
220
|
-
const langTable:PRecord<LangFlag,string> = {
|
|
221
|
-
[SI18n._table!.base_lang]:dat.original,
|
|
222
|
-
...dat.lang_table
|
|
223
|
-
};
|
|
224
|
-
if(langTable[lang]!=undefined) return langTable[lang]!;
|
|
225
|
-
const l1 = lang.match(/^([^-]+)/)![1];
|
|
226
|
-
const rb = Object.entries(langTable).find(([k,v])=>k.includes(l1));
|
|
227
|
-
if(rb) return rb[1];
|
|
228
|
-
return dat.original;
|
|
229
|
-
}
|
|
230
|
-
/**覆盖性的添加一处原文 */
|
|
231
|
-
static addOriginalText(dat:I18nTextData){
|
|
232
|
-
const key = SI18n.formatI18nKey(dat.original,dat.mark);
|
|
233
|
-
SI18n._table!.text_table[key] = dat;
|
|
234
|
-
return SI18n._table!.text_table[key];
|
|
235
|
-
}
|
|
236
|
-
/**保存数据 */
|
|
237
|
-
static async saveTable(){
|
|
238
|
-
const {text_table,...rest} = SI18n._table!;
|
|
239
|
-
const date = new Date().toISOString();
|
|
240
|
-
//console.log(text_table)
|
|
241
|
-
|
|
242
|
-
//保存原始文本数据
|
|
243
|
-
const tb:I18nOrigTable = {
|
|
244
|
-
...rest,
|
|
245
|
-
texts:Object.values(text_table).map((d)=>{
|
|
246
|
-
const {lang_table,...rest} = d;
|
|
247
|
-
return rest;
|
|
248
|
-
})
|
|
249
|
-
}
|
|
250
|
-
const mergePath = path.join(SI18n._dataDir!,BaseFile);
|
|
251
|
-
await UtilFT.writeJSONFile(mergePath,tb);
|
|
252
|
-
|
|
253
|
-
//保存所有语言数据
|
|
254
|
-
const tbMap:PRecord<LangFlag,I18nSingleTable> = {};
|
|
255
|
-
Object.values(text_table).forEach(d=>{
|
|
256
|
-
if(d.invalid===true) return;
|
|
257
|
-
SI18n._vaildLang?.forEach((vl)=>{
|
|
258
|
-
const lf = vl as LangFlag;
|
|
259
|
-
tbMap[lf] ??={
|
|
260
|
-
base_lang:rest.base_lang,
|
|
261
|
-
modify_time:date,
|
|
262
|
-
target_lang:lf,
|
|
263
|
-
translate_table:{}
|
|
264
|
-
}
|
|
265
|
-
const v = d.lang_table[lf];
|
|
266
|
-
tbMap[lf]!.translate_table[SI18n.formatI18nKey(d.original,d.mark)] = v ?? null;
|
|
267
|
-
})
|
|
268
|
-
});
|
|
269
|
-
await Promise.all(Object.values(tbMap).map(async (t)=>{
|
|
270
|
-
if(t.target_lang == 'template' as LangFlag){
|
|
271
|
-
const tmppath = path.join(SI18n._dataDir!,TemplateFile);
|
|
272
|
-
return await UtilFT.writeJSONFile(tmppath,t);
|
|
273
|
-
}
|
|
274
|
-
const singlePath = path.join(SI18n._dataDir!,LangDir,t.target_lang);
|
|
275
|
-
return await UtilFT.writeJSONFile(singlePath,t);
|
|
276
|
-
}))
|
|
277
|
-
}
|
|
278
|
-
}
|
package/src/UtilInterfaces.ts
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import { Failed, Success, Terminated } from "./UtilSymbol";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
/**可以序列化为JSON文件的对象 */
|
|
5
|
-
export type JToken = JObject|JArray|JValue|IJData;
|
|
6
|
-
/**在stringify输出时 undefine 会被转为 null */
|
|
7
|
-
export type JValue = number|string|boolean|null|undefined;
|
|
8
|
-
/**在stringify输出时 值为 undefine 的成员会被转为 null */
|
|
9
|
-
export type JArray = Array<JToken>;
|
|
10
|
-
/**在stringify输出时 值为 undefine 的键会被忽略 */
|
|
11
|
-
export type JObject = {
|
|
12
|
-
[key:string]:JToken;
|
|
13
|
-
}
|
|
14
|
-
/**可以保存为JToken的类 */
|
|
15
|
-
export interface IJData{
|
|
16
|
-
/**保存为JToken
|
|
17
|
-
*/
|
|
18
|
-
toJSON():JToken;
|
|
19
|
-
}
|
|
20
|
-
/**任何可能有ReturnType的函数 */
|
|
21
|
-
export type AnyFunc = (...args:any)=>any;
|
|
22
|
-
|
|
23
|
-
/**任意可作为键值的类型 */
|
|
24
|
-
export type Keyable = string | number | symbol;
|
|
25
|
-
|
|
26
|
-
/**排除可选项目
|
|
27
|
-
* 将基础类型中与默认选项重合的部分变为可选
|
|
28
|
-
* @template B - 基础类型
|
|
29
|
-
* @template D - 默认选项
|
|
30
|
-
*/
|
|
31
|
-
export type PartialOption<B,D> = keyof D extends keyof B
|
|
32
|
-
? Omit<B,keyof D> & Partial<Pick<B,keyof D>>
|
|
33
|
-
: never;
|
|
34
|
-
|
|
35
|
-
/**真子集 测试 T 是否为 B 的真子集
|
|
36
|
-
* @template B - 超集
|
|
37
|
-
* @template T - 子集
|
|
38
|
-
*/
|
|
39
|
-
export type ProperSubset<B, T> = T extends B ? B extends T ? never : T : never;
|
|
40
|
-
/**真子集检查 测试 T 是否为 B 的真子集
|
|
41
|
-
* 相等时返回 'E'
|
|
42
|
-
* 真子集时返回 'P'
|
|
43
|
-
* 不相交时返回 'N'
|
|
44
|
-
* @template B - 超集
|
|
45
|
-
* @template T - 子集
|
|
46
|
-
*/
|
|
47
|
-
export type ProperSubsetCheck<B, T> = T extends B ? B extends T ? "E" : "P" : "N";
|
|
48
|
-
|
|
49
|
-
/**字面量 检查 L 是否为字面量
|
|
50
|
-
* @template L - 目标量
|
|
51
|
-
*/
|
|
52
|
-
export type Literal<L> =
|
|
53
|
-
ProperSubset<string , L> |
|
|
54
|
-
ProperSubset<number , L> |
|
|
55
|
-
ProperSubset<boolean, L> |
|
|
56
|
-
ProperSubset<symbol , L> |
|
|
57
|
-
ProperSubset<any[] , L> |
|
|
58
|
-
ProperSubset<Record<any,any>, L> |
|
|
59
|
-
Extract<L, null | undefined>;
|
|
60
|
-
|
|
61
|
-
/**字面量检查 测试 L 是否为字面量
|
|
62
|
-
* 是字面量时返回 true
|
|
63
|
-
* 不是字面量时返回 false
|
|
64
|
-
* @template L - 目标量
|
|
65
|
-
*/
|
|
66
|
-
export type LiteralCheck<L> =
|
|
67
|
-
ProperSubsetCheck<string , L> extends "P" ? true :
|
|
68
|
-
ProperSubsetCheck<number , L> extends "P" ? true :
|
|
69
|
-
ProperSubsetCheck<boolean, L> extends "P" ? true :
|
|
70
|
-
ProperSubsetCheck<symbol , L> extends "P" ? true :
|
|
71
|
-
ProperSubsetCheck<any[] , L> extends "P" ? true :
|
|
72
|
-
ProperSubsetCheck<Record<any,any>, L> extends "P" ? true :
|
|
73
|
-
L extends null | undefined ? true : false;
|
|
74
|
-
|
|
75
|
-
/**递归判断元组 List 每个元素是否 extends T */
|
|
76
|
-
export type AllExtends<List extends any[], T> =
|
|
77
|
-
List extends [infer First, ...infer Rest]
|
|
78
|
-
? First extends T
|
|
79
|
-
? AllExtends<Rest,T>
|
|
80
|
-
: false
|
|
81
|
-
: true;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
/**返回将Mixin分配给Base的结果,相同字段时Mixin覆盖Base */
|
|
85
|
-
export type AssignObject<Base extends AnyRecord, Mixin extends AnyRecord> = {
|
|
86
|
-
[P in keyof Mixin | keyof Base]: P extends keyof Mixin ? Mixin[P] : P extends keyof Base ? Base[P] : never;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**转为可写的 */
|
|
90
|
-
export type Writeable<T> = {
|
|
91
|
-
-readonly [P in keyof T]: T[P]
|
|
92
|
-
};
|
|
93
|
-
/**翻转K和V */
|
|
94
|
-
export type Inverted<T extends Record<keyof T, string | number | symbol>> = {
|
|
95
|
-
[K in keyof T as T[K]]: K;
|
|
96
|
-
};
|
|
97
|
-
/**N长度 T类型的元组 */
|
|
98
|
-
export type FixedLengthTuple<T, N extends number, R extends unknown[] = []> =
|
|
99
|
-
R['length'] extends N ? R : FixedLengthTuple<T, N, [T, ...R]>;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
/**不影响智能补全的任意字符串
|
|
103
|
-
* (string&Object)
|
|
104
|
-
* (string&String)
|
|
105
|
-
*/
|
|
106
|
-
export type AnyString = (string&{});
|
|
107
|
-
|
|
108
|
-
/**联合类型转为交叉类型
|
|
109
|
-
* 利用分布式条件将U展开为联合函数(k:U1)=>void | (k:U2)=>void
|
|
110
|
-
* 再从中提取可以传递给任意联合函数的类型
|
|
111
|
-
*/
|
|
112
|
-
export type UnionToIntersection<U> =
|
|
113
|
-
(U extends any
|
|
114
|
-
? (k: U)=>void
|
|
115
|
-
: never) extends ((k: infer I)=>void)
|
|
116
|
-
? I
|
|
117
|
-
: never
|
|
118
|
-
|
|
119
|
-
/**创建一个新的类型,这个新的类型包含了基础类型 B 的所有属性,
|
|
120
|
-
* 以及一个名为 K[N] 类型为 T 的新属性。
|
|
121
|
-
* 所有 K 中非 K[N] 的其他属性都是可选的并且不能被赋值(因为它们的类型是 never)。
|
|
122
|
-
*/
|
|
123
|
-
type ExclusiveSub<B, T, K extends string[], N extends number> =
|
|
124
|
-
B & { [P in K[N]]: T } & { [P in Exclude<K[number], K[N]>]?: never };
|
|
125
|
-
|
|
126
|
-
/**递归地创建一个元组类型, 所有成员类型都有一个 K[number] 键 并且与其他成员互斥
|
|
127
|
-
* 这个元组类型的每个元素都是通过 ExclusiveSub 类型创建的。
|
|
128
|
-
*/
|
|
129
|
-
type ExclusiveRecursive<B, T, K extends string[], R extends unknown[] = []> =
|
|
130
|
-
R['length'] extends K['length'] ? R
|
|
131
|
-
: ExclusiveRecursive<B, T, K, [ExclusiveSub<B, T, K, R['length']>, ...R]>;
|
|
132
|
-
|
|
133
|
-
/**互斥表
|
|
134
|
-
* 从 ExclusiveRecursive 类型创建的元组中创建一个或类型, 可以是任意一个元组元素类型
|
|
135
|
-
*/
|
|
136
|
-
export type ExclusiveRecord<B, T, K extends string[], TMP = ExclusiveRecursive<B, T, K>> = TMP[keyof TMP];
|
|
137
|
-
|
|
138
|
-
/**符合JObject约束的互斥表 */
|
|
139
|
-
export type ExclusiveJObject<B extends JObject,T extends JToken,K extends string[],
|
|
140
|
-
TMP extends JArray = ExclusiveRecursive<B,T,K>> = TMP[number];
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
/**Promise完成状态 成功/失败/终止
|
|
144
|
-
* 成功 将直接返回 结果
|
|
145
|
-
* 终止 将直接返回 结果
|
|
146
|
-
* 失败 将重试
|
|
147
|
-
*/
|
|
148
|
-
export type PromiseStatus = Success|Failed|Terminated;
|
|
149
|
-
/**状态验证函数 */
|
|
150
|
-
export type StatusVerifyFn<T> = (obj:T)=>Promise<PromiseStatus>|PromiseStatus;
|
|
151
|
-
|
|
152
|
-
/**获取Promise的结果类型 如同await那样
|
|
153
|
-
* @deprecated 请使用官方的 Awaited<T> 类型
|
|
154
|
-
*/
|
|
155
|
-
export type Await<T> = T extends Promise<infer U> ? U : T;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
/**类型中任意函数的字符串名称 */
|
|
159
|
-
export type FuncPropNames<T> = {
|
|
160
|
-
[K in keyof T]: T[K] extends AnyFunc ? K : never;
|
|
161
|
-
}[keyof T];
|
|
162
|
-
|
|
163
|
-
/** extends封装
|
|
164
|
-
* @template B - 基础类型
|
|
165
|
-
* @template T - 判断的目标类型
|
|
166
|
-
* @template Y - 如果为真的返回值
|
|
167
|
-
* @template N - 如果为假的返回值
|
|
168
|
-
*/
|
|
169
|
-
export type ExtendThen<B,T,Y,N = never> = B extends T ? Y : N;
|
|
170
|
-
/** 一个联合类型 B 中如果包含 联合类型 T 中的任意项
|
|
171
|
-
* 无效
|
|
172
|
-
* @template B - 基础类型
|
|
173
|
-
* @template T - 判断的目标类型
|
|
174
|
-
* @template Y - 如果为真的返回值
|
|
175
|
-
* @template N - 如果为假的返回值
|
|
176
|
-
*/
|
|
177
|
-
type UnionInclude<B,T,Y,N = never> =
|
|
178
|
-
B extends Exclude<B,T>
|
|
179
|
-
? N : Y
|
|
180
|
-
/**排除可选字段 */
|
|
181
|
-
export type RequiredOnly<T> = {
|
|
182
|
-
[K in keyof T as
|
|
183
|
-
T[K] extends Exclude<T[K],undefined>
|
|
184
|
-
? K
|
|
185
|
-
: never
|
|
186
|
-
]: T[K]
|
|
187
|
-
};
|
|
188
|
-
/**添加前缀 */
|
|
189
|
-
export type WithPrefix<T,P extends string> = {
|
|
190
|
-
[K in (keyof T) as
|
|
191
|
-
K extends string
|
|
192
|
-
? `${P}${K}`
|
|
193
|
-
: K
|
|
194
|
-
]: T[K]
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
/**附带状态的返回结果用于状态返回值的封装
|
|
198
|
-
* @template K - 类型键值
|
|
199
|
-
* @template V - 值
|
|
200
|
-
*/
|
|
201
|
-
export type Outcome<K extends Keyable,V> = {
|
|
202
|
-
/**状态类型 */
|
|
203
|
-
readonly status:K;
|
|
204
|
-
/**值 */
|
|
205
|
-
readonly result:V;
|
|
206
|
-
}
|
|
207
|
-
/**可进行匹配的对象
|
|
208
|
-
* 如果是Outcome则自动处理status
|
|
209
|
-
*/
|
|
210
|
-
export type Matchable<T extends Keyable> = T|Outcome<T,unknown>;
|
|
211
|
-
/**可进行匹配的 outcome或symbol 中的状态类型 */
|
|
212
|
-
export type MatchableFlag<T> =
|
|
213
|
-
T extends infer O|Outcome<infer O,unknown>
|
|
214
|
-
? O : never;
|
|
215
|
-
|
|
216
|
-
/**从联合 Outcome 中 根据 K 提取对应 Outcome
|
|
217
|
-
* @template T - 联合Outcome匹配的类型
|
|
218
|
-
* @template K - 所需的状态
|
|
219
|
-
*/
|
|
220
|
-
export type ExtractOutcome<T,K extends Keyable> =
|
|
221
|
-
T extends Outcome<infer O,unknown>
|
|
222
|
-
? O extends Exclude<O,K>
|
|
223
|
-
? never : T
|
|
224
|
-
: never;
|
|
225
|
-
|
|
226
|
-
/**用于辅助解析智能补全的类型
|
|
227
|
-
* 输出schema后替换为 ^.*$ 的 string 匹配
|
|
228
|
-
*/
|
|
229
|
-
export type SchemaString = `${string}SchemaString`;
|
|
230
|
-
|
|
231
|
-
/**需要初始化 */
|
|
232
|
-
export type NeedInit = {
|
|
233
|
-
/**完成初始化的标记 */
|
|
234
|
-
inited: Promise<any>;
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
/**可选的record PartialRecord */
|
|
238
|
-
export type PRecord<K extends Keyable,V> = Partial<Record<K,V>>;
|
|
239
|
-
/** 可以是Promise MaybePromise*/
|
|
240
|
-
export type MPromise<T> = T | Promise<T>;
|
|
241
|
-
/**任何Record */
|
|
242
|
-
export type AnyRecord = Record<Keyable,any>;
|
|
243
|
-
|
|
244
|
-
/**注释元组
|
|
245
|
-
* @template T - 提供注释的类型, 索引需从0开始
|
|
246
|
-
*/
|
|
247
|
-
export type CmtTuple<T extends {[K:number]:unknown},Tuple extends unknown[]=[]> =
|
|
248
|
-
unknown extends T[Tuple['length']]
|
|
249
|
-
? T & Tuple
|
|
250
|
-
: CmtTuple<T,[...Tuple,T[Tuple['length']]]>;
|
|
251
|
-
|
|
252
|
-
/**非严格模式下将会判断为false的值, 不包含NaN */
|
|
253
|
-
export type Flasy = false | 0 | -0 | "" | null | undefined;
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
/**srt段 */
|
|
257
|
-
export type SrtSegment = {
|
|
258
|
-
/**开始时间, 以毫秒为单位 */
|
|
259
|
-
start: number;
|
|
260
|
-
/**结束时间, 以毫秒为单位 */
|
|
261
|
-
end : number;
|
|
262
|
-
/**字幕文本 */
|
|
263
|
-
text : string;
|
|
264
|
-
};
|