@zwa73/utils 1.0.71 → 1.0.72
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/UtilFP.d.ts +1 -1
- package/dist/UtilFunctions.d.ts +4 -10
- package/dist/UtilFunctions.js +34 -57
- package/dist/UtilInterfaces.d.ts +11 -30
- package/dist/UtilInterfaces.js +1 -10
- package/dist/backup.d.ts +32 -0
- package/dist/backup.js +48 -0
- package/dist/test/composeTest.d.ts +56 -7
- package/dist/test/composeTest.js +43 -6
- package/dist/test/test.js +3 -53
- package/package.json +1 -1
- package/src/UtilFP.ts +1 -1
- package/src/UtilFunctions.ts +36 -61
- package/src/UtilInterfaces.ts +13 -69
- package/src/backup.ts +102 -0
- package/src/test/composeTest.ts +49 -7
- package/src/test/test.ts +5 -63
package/dist/UtilFP.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**常用函数式编程库 */
|
|
2
2
|
export declare namespace UtilFP {
|
|
3
3
|
/**柯里化函数类型 */
|
|
4
|
-
type CurryFunc<T, PrevArgs extends
|
|
4
|
+
type CurryFunc<T, PrevArgs extends unknown[] = []> = T extends (...args: infer Args) => infer Result ? Args extends [infer Arg, ...infer RestArgs] ? RestArgs extends [] ? (...args: [...PrevArgs, Arg]) => Result : (...args: [...PrevArgs, Arg]) => CurryFunc<(...rest: RestArgs) => Result> & CurryFunc<(...args: RestArgs) => Result, [...PrevArgs, Arg]> : Args extends [] ? () => Result : "CurryFunc错误 可选无法被识别" & Error : never;
|
|
5
5
|
/**柯里化转换
|
|
6
6
|
* @param {T} fn - 将要转换的函数
|
|
7
7
|
* @returns {CurryFunc<T>} 柯里化的函数
|
package/dist/UtilFunctions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComposedClass, ComposedMixinable, JToken, Mixinable, PromiseProcFn, PromiseVerifyFn } from "./UtilInterfaces";
|
|
2
2
|
/**常用函数 */
|
|
3
3
|
export declare namespace UtilFunc {
|
|
4
4
|
/**获取当前时间戳
|
|
@@ -61,19 +61,13 @@ export declare namespace UtilFunc {
|
|
|
61
61
|
* 将mixin的部分字段混入base
|
|
62
62
|
* @param base - 基础类
|
|
63
63
|
* @param mixin - 目标类
|
|
64
|
+
* @param key - mixin 对象在 base 中的 key
|
|
64
65
|
* @param fields - 需要混入的字段
|
|
65
66
|
* @returns 混合完成的类
|
|
66
67
|
*/
|
|
67
|
-
function composeClassPart<Base extends object, Mixin extends object, Field extends keyof Mixin>(base: Base, mixin: Mixin, ...fields: Field[]):
|
|
68
|
+
function composeClassPart<Base extends object, Mixin extends object, Field extends keyof Mixin>(base: Base, mixin: Mixin, key: string, ...fields: Field[]): ComposedClass<Base, Mixin, typeof key, Field>;
|
|
68
69
|
/**根据 MIXIN_FIELDS 自动混入 */
|
|
69
|
-
function composeMixinable<
|
|
70
|
-
/**类组合
|
|
71
|
-
* 将mixinList每个成员的字段混入base
|
|
72
|
-
* @param base - 基础类
|
|
73
|
-
* @param mixinList - 目标类
|
|
74
|
-
* @returns - 混合完成的类
|
|
75
|
-
*/
|
|
76
|
-
function composeClass<Base extends object, MixinList extends object[]>(base: Base, ...mixinList: MixinList): ComposedClassMult<Base, MixinList>;
|
|
70
|
+
function composeMixinable<Base extends object, Mixins extends Mixinable<any>[]>(base: Base, ...mixins: Mixins): ComposedMixinable<Base, Mixins>;
|
|
77
71
|
/**对对象的每个属性应用映射函数,并返回一个新的对象。
|
|
78
72
|
* @template T - 对象的类型
|
|
79
73
|
* @param obj - 要处理的对象
|
package/dist/UtilFunctions.js
CHANGED
|
@@ -201,81 +201,58 @@ var UtilFunc;
|
|
|
201
201
|
* 将mixin的部分字段混入base
|
|
202
202
|
* @param base - 基础类
|
|
203
203
|
* @param mixin - 目标类
|
|
204
|
+
* @param key - mixin 对象在 base 中的 key
|
|
204
205
|
* @param fields - 需要混入的字段
|
|
205
206
|
* @returns 混合完成的类
|
|
206
207
|
*/
|
|
207
|
-
function composeClassPart(base, mixin, ...fields) {
|
|
208
|
+
function composeClassPart(base, mixin, key, ...fields) {
|
|
208
209
|
const compObj = base;
|
|
210
|
+
compObj[key] = mixin;
|
|
209
211
|
for (const fd of fields) {
|
|
210
|
-
|
|
212
|
+
if (compObj[fd] !== undefined)
|
|
213
|
+
UtilLogger_1.SLogger.warn(`${fd} 已存在于基础类中, 混入可能导致类型问题, 如需覆盖, 请使用 ${key}=val`);
|
|
211
214
|
Object.defineProperty(compObj, fd, {
|
|
212
|
-
get: ()=>
|
|
213
|
-
set: (value)=>{
|
|
214
|
-
enumerable:true
|
|
215
|
+
get: () => compObj[key][fd],
|
|
216
|
+
set: (value) => { compObj[key][fd] = value; },
|
|
217
|
+
enumerable: true,
|
|
215
218
|
//writable: true ,
|
|
216
219
|
configurable: true
|
|
217
220
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
221
|
+
//if(typeof mixin[fd] === 'function') {
|
|
222
|
+
// compObj[fd] = (...args: any[]) => compObj[key][fd](...args);
|
|
223
|
+
// //(compObj as any)[fd] = (...args: any[]) => (mixin[fd] as any).apply(mixin, args);
|
|
224
|
+
// //(compObj as any)[fd] = (mixin[fd] as any).bind(mixin);
|
|
225
|
+
//} else {
|
|
226
|
+
// Object.defineProperty(compObj, fd, {
|
|
227
|
+
// get: ()=>compObj[key][fd],
|
|
228
|
+
// set: (value)=>{compObj[key][fd] = value},
|
|
229
|
+
// enumerable:true ,
|
|
230
|
+
// //writable: true ,
|
|
231
|
+
// configurable: true
|
|
232
|
+
// });
|
|
233
|
+
//}
|
|
232
234
|
}
|
|
233
235
|
return compObj;
|
|
234
236
|
}
|
|
235
237
|
UtilFunc.composeClassPart = composeClassPart;
|
|
238
|
+
/**根据 MIXIN_FIELDS 自动混入 */
|
|
236
239
|
function composeMixinable(base, ...mixins) {
|
|
237
240
|
let out = base;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
* @returns - 混合完成的类
|
|
248
|
-
*/
|
|
249
|
-
function composeClass(base, ...mixinList) {
|
|
250
|
-
let obj = base;
|
|
251
|
-
for (let mixin of mixinList) {
|
|
252
|
-
let propks = Object.getOwnPropertyNames(mixin.constructor.prototype);
|
|
253
|
-
for (const key of propks) {
|
|
254
|
-
if (key != "constructor") {
|
|
255
|
-
Object.defineProperty(obj, key, {
|
|
256
|
-
get: () => mixin[key],
|
|
257
|
-
set: (value) => { mixin[key] = value; },
|
|
258
|
-
enumerable: true,
|
|
259
|
-
//writable: true,
|
|
260
|
-
configurable: true
|
|
261
|
-
});
|
|
262
|
-
//obj[key] = (mixin as any)[key];
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
for (const key in mixin) {
|
|
266
|
-
Object.defineProperty(obj, key, {
|
|
267
|
-
get: () => mixin[key],
|
|
268
|
-
set: (value) => { mixin[key] = value; },
|
|
269
|
-
enumerable: true,
|
|
270
|
-
//writable: true ,
|
|
271
|
-
configurable: true
|
|
272
|
-
});
|
|
273
|
-
//obj[key] = (mixin as any)[key];
|
|
241
|
+
const fieldsSet = new Set();
|
|
242
|
+
for (const rawmixin of mixins) {
|
|
243
|
+
const mixin = rawmixin;
|
|
244
|
+
for (const field of mixin.MIXIN_FIELDS) {
|
|
245
|
+
const fixField = field;
|
|
246
|
+
if (fieldsSet.has(fixField))
|
|
247
|
+
UtilLogger_1.SLogger.warn(`composeMixinable 出现了重复的 field: ${fixField} 可能会导致问题`);
|
|
248
|
+
else
|
|
249
|
+
fieldsSet.add(fixField);
|
|
274
250
|
}
|
|
251
|
+
out = composeClassPart(base, mixin, mixin.MIXIN_KEY, ...mixin.MIXIN_FIELDS);
|
|
275
252
|
}
|
|
276
|
-
return
|
|
253
|
+
return out;
|
|
277
254
|
}
|
|
278
|
-
UtilFunc.
|
|
255
|
+
UtilFunc.composeMixinable = composeMixinable;
|
|
279
256
|
/**对对象的每个属性应用映射函数,并返回一个新的对象。
|
|
280
257
|
* @template T - 对象的类型
|
|
281
258
|
* @param obj - 要处理的对象
|
package/dist/UtilInterfaces.d.ts
CHANGED
|
@@ -72,39 +72,20 @@ export type FuncPropNames<T> = {
|
|
|
72
72
|
* @template Mixin - 待混入的类
|
|
73
73
|
* @template PropKeys - 需要混入的成员key
|
|
74
74
|
*/
|
|
75
|
-
export type
|
|
76
|
-
|
|
77
|
-
export type ComposedPartClassMult<Base extends object, Mixin1 extends object = {}, PropKeys1 extends keyof Mixin1 = keyof Mixin1, Mixin2 extends object = {}, PropKeys2 extends keyof Mixin2 = keyof Mixin2, Mixin3 extends object = {}, PropKeys3 extends keyof Mixin3 = keyof Mixin3, Mixin4 extends object = {}, PropKeys4 extends keyof Mixin4 = keyof Mixin4, Mixin5 extends object = {}, PropKeys5 extends keyof Mixin5 = keyof Mixin5, Mixin6 extends object = {}, PropKeys6 extends keyof Mixin6 = keyof Mixin6> = ComposedClassPart<ComposedClassPart<ComposedClassPart<ComposedClassPart<ComposedClassPart<ComposedClassPart<Base, Mixin1, PropKeys1>, Mixin2, PropKeys2>, Mixin3, PropKeys3>, Mixin4, PropKeys4>, Mixin5, PropKeys5>, Mixin6, PropKeys6>;
|
|
78
|
-
/**组合的类
|
|
79
|
-
* @template Base - 基类
|
|
80
|
-
* @template Mixin - 待混入的类
|
|
81
|
-
*/
|
|
82
|
-
export type ComposedClass<Base extends object, Mixin extends object> = Base & Mixin;
|
|
83
|
-
/**组合的类 多组合变体
|
|
84
|
-
* @template Base - 基类
|
|
85
|
-
* @template MixinList- 待混入的类型数组
|
|
86
|
-
*/
|
|
87
|
-
export type ComposedClassMult<Base extends object, MixinList extends object[]> = MixinList extends [infer Mixin, ...infer Rest] ? Mixin extends object ? Rest extends object[] ? ComposedClassMult<ComposedClass<Base, Mixin>, Rest> : Base : Base : Base;
|
|
88
|
-
/**将一个类型的所有方法的 `this` 参数改为 `T` 类型
|
|
89
|
-
* @template Methods - 待更改的函数表
|
|
90
|
-
* @template T - 目标this类型
|
|
91
|
-
*/
|
|
92
|
-
export type MethodsThisAs<Methods, T> = {
|
|
93
|
-
[K in keyof Methods]: Methods[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : Methods[K];
|
|
75
|
+
export type ComposedClass<Base extends object, Mixin extends object, Key extends string, PropKeys extends keyof Mixin> = Base & Pick<Mixin, PropKeys> & {
|
|
76
|
+
[P in Key]: Mixin;
|
|
94
77
|
};
|
|
95
|
-
/**尝试断言一个类的原型
|
|
96
|
-
* 其所有函数的 this 都必须为某个类型
|
|
97
|
-
* assignThisAs<Self,T>(Self.prototype);
|
|
98
|
-
* @template Self - 类的类型
|
|
99
|
-
* @template T - 目标this类型
|
|
100
|
-
* @param prototype - 类的原型
|
|
101
|
-
*/
|
|
102
|
-
export declare function assertThisAs<Self, T>(prototype: MethodsThisAs<Self, T>): void;
|
|
103
78
|
/**可自动混入的类型 */
|
|
104
79
|
export type Mixinable<Mixin> = {
|
|
105
|
-
|
|
106
|
-
|
|
80
|
+
/**混入时自身所在位置
|
|
81
|
+
* 请使用字面量
|
|
82
|
+
*/
|
|
83
|
+
readonly MIXIN_KEY: string;
|
|
84
|
+
/**可混入的字段
|
|
85
|
+
* 请使用字面量
|
|
86
|
+
*/
|
|
87
|
+
readonly MIXIN_FIELDS: readonly (keyof Mixin)[];
|
|
107
88
|
};
|
|
108
89
|
/**自动组合可混入的类 */
|
|
109
|
-
export type ComposedMixinable<B extends object, Ms extends
|
|
90
|
+
export type ComposedMixinable<B extends object, Ms extends unknown[]> = Ms extends [infer M, ...infer Rest] ? M extends Mixinable<M> ? ComposedMixinable<ComposedClass<B, M, M['MIXIN_KEY'], M['MIXIN_FIELDS'][number]>, Rest> : "一个混入类没有实现 Mixinable<self>" & Error : B;
|
|
110
91
|
export {};
|
package/dist/UtilInterfaces.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.stringifyJToken = void 0;
|
|
4
4
|
/**将JToken转换为字符串
|
|
5
5
|
* @param token - 待转换的Token
|
|
6
6
|
* @param space - 插入的空格 数字为空格数量 默认为制表符\t
|
|
@@ -12,12 +12,3 @@ function stringifyJToken(token, space = "\t") {
|
|
|
12
12
|
return JSON.stringify(token, null, space);
|
|
13
13
|
}
|
|
14
14
|
exports.stringifyJToken = stringifyJToken;
|
|
15
|
-
/**尝试断言一个类的原型
|
|
16
|
-
* 其所有函数的 this 都必须为某个类型
|
|
17
|
-
* assignThisAs<Self,T>(Self.prototype);
|
|
18
|
-
* @template Self - 类的类型
|
|
19
|
-
* @template T - 目标this类型
|
|
20
|
-
* @param prototype - 类的原型
|
|
21
|
-
*/
|
|
22
|
-
function assertThisAs(prototype) { }
|
|
23
|
-
exports.assertThisAs = assertThisAs;
|
package/dist/backup.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**类组合
|
|
2
|
+
* 将mixinList每个成员的字段混入base
|
|
3
|
+
* @param base - 基础类
|
|
4
|
+
* @param mixinList - 目标类
|
|
5
|
+
* @returns - 混合完成的类
|
|
6
|
+
*/
|
|
7
|
+
export declare function composeClassFull<Base extends object, MixinList extends object[]>(base: Base, ...mixinList: MixinList): ComposedFullClassMult<Base, MixinList>;
|
|
8
|
+
/**组合的类
|
|
9
|
+
* @template Base - 基类
|
|
10
|
+
* @template Mixin - 待混入的类
|
|
11
|
+
*/
|
|
12
|
+
export type ComposedFullClass<Base extends object, Mixin extends object> = Base & Mixin;
|
|
13
|
+
/**组合的类 多组合变体
|
|
14
|
+
* @template Base - 基类
|
|
15
|
+
* @template MixinList- 待混入的类型数组
|
|
16
|
+
*/
|
|
17
|
+
export type ComposedFullClassMult<Base extends object, MixinList extends object[]> = MixinList extends [infer Mixin, ...infer Rest] ? Mixin extends object ? Rest extends object[] ? ComposedFullClassMult<ComposedFullClass<Base, Mixin>, Rest> : Base : Base : Base;
|
|
18
|
+
/**将一个类型的所有方法的 `this` 参数改为 `T` 类型
|
|
19
|
+
* @template Methods - 待更改的函数表
|
|
20
|
+
* @template T - 目标this类型
|
|
21
|
+
*/
|
|
22
|
+
export type MethodsThisAs<Methods, T> = {
|
|
23
|
+
[K in keyof Methods]: Methods[K] extends (...args: infer A) => infer R ? (this: T, ...args: A) => R : Methods[K];
|
|
24
|
+
};
|
|
25
|
+
/**尝试断言一个类的原型
|
|
26
|
+
* 其所有函数的 this 都必须为某个类型
|
|
27
|
+
* assignThisAs<Self,T>(Self.prototype);
|
|
28
|
+
* @template Self - 类的类型
|
|
29
|
+
* @template T - 目标this类型
|
|
30
|
+
* @param prototype - 类的原型
|
|
31
|
+
*/
|
|
32
|
+
export declare function assertThisAs<Self, T>(prototype: MethodsThisAs<Self, T>): void;
|
package/dist/backup.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertThisAs = exports.composeClassFull = void 0;
|
|
4
|
+
/**类组合
|
|
5
|
+
* 将mixinList每个成员的字段混入base
|
|
6
|
+
* @param base - 基础类
|
|
7
|
+
* @param mixinList - 目标类
|
|
8
|
+
* @returns - 混合完成的类
|
|
9
|
+
*/
|
|
10
|
+
function composeClassFull(base, ...mixinList) {
|
|
11
|
+
let obj = base;
|
|
12
|
+
for (let mixin of mixinList) {
|
|
13
|
+
let propks = Object.getOwnPropertyNames(mixin.constructor.prototype);
|
|
14
|
+
for (const key of propks) {
|
|
15
|
+
if (key != "constructor") {
|
|
16
|
+
Object.defineProperty(obj, key, {
|
|
17
|
+
get: () => mixin[key],
|
|
18
|
+
set: (value) => { mixin[key] = value; },
|
|
19
|
+
enumerable: true,
|
|
20
|
+
//writable: true,
|
|
21
|
+
configurable: true
|
|
22
|
+
});
|
|
23
|
+
//obj[key] = (mixin as any)[key];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const key in mixin) {
|
|
27
|
+
Object.defineProperty(obj, key, {
|
|
28
|
+
get: () => mixin[key],
|
|
29
|
+
set: (value) => { mixin[key] = value; },
|
|
30
|
+
enumerable: true,
|
|
31
|
+
//writable: true ,
|
|
32
|
+
configurable: true
|
|
33
|
+
});
|
|
34
|
+
//obj[key] = (mixin as any)[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return obj;
|
|
38
|
+
}
|
|
39
|
+
exports.composeClassFull = composeClassFull;
|
|
40
|
+
/**尝试断言一个类的原型
|
|
41
|
+
* 其所有函数的 this 都必须为某个类型
|
|
42
|
+
* assignThisAs<Self,T>(Self.prototype);
|
|
43
|
+
* @template Self - 类的类型
|
|
44
|
+
* @template T - 目标this类型
|
|
45
|
+
* @param prototype - 类的原型
|
|
46
|
+
*/
|
|
47
|
+
function assertThisAs(prototype) { }
|
|
48
|
+
exports.assertThisAs = assertThisAs;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Mixinable } from "..";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
type MixinA = Mixinable<A>;
|
|
3
|
+
declare class A implements MixinA {
|
|
4
|
+
anum: number;
|
|
5
|
+
constructor(n?: number);
|
|
4
6
|
getNum: () => number;
|
|
5
7
|
/**A的函数 */
|
|
6
8
|
getA: () => this;
|
|
7
|
-
|
|
9
|
+
readonly MIXIN_KEY: "__a";
|
|
10
|
+
static MIXIN_FIELDS: readonly ["getNum", "getA", "anum"];
|
|
11
|
+
readonly MIXIN_FIELDS: readonly ["getNum", "getA", "anum"];
|
|
8
12
|
}
|
|
9
13
|
declare class B implements Mixinable<B> {
|
|
10
14
|
private text;
|
|
@@ -15,15 +19,60 @@ declare class B implements Mixinable<B> {
|
|
|
15
19
|
static getNewB: () => B;
|
|
16
20
|
/**保留的函数 */
|
|
17
21
|
privateFunc(): void;
|
|
18
|
-
|
|
22
|
+
readonly MIXIN_KEY: "__b";
|
|
23
|
+
static readonly MIXIN_FIELDS: readonly ["getText", "getB"];
|
|
24
|
+
readonly MIXIN_FIELDS: readonly ["getText", "getB"];
|
|
19
25
|
}
|
|
20
26
|
declare class _C {
|
|
21
|
-
static create(): _C & Pick<B, "getText" | "getB"> &
|
|
27
|
+
static create(): _C & Pick<B, "getText" | "getB"> & {
|
|
28
|
+
__b: B;
|
|
29
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
30
|
+
__a: A;
|
|
31
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
22
32
|
private constructor();
|
|
23
|
-
getC(this: C): _C & Pick<B, "getText" | "getB"> &
|
|
33
|
+
getC(this: C): _C & Pick<B, "getText" | "getB"> & {
|
|
34
|
+
__b: B;
|
|
35
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
36
|
+
__a: A;
|
|
37
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
24
38
|
testFunc(this: C): number;
|
|
39
|
+
readonly MIXIN_KEY: "__c";
|
|
40
|
+
static readonly MIXIN_FIELDS: readonly ["getNum", "getA", "anum", "getText", "getB", "getC", "__a"];
|
|
41
|
+
readonly MIXIN_FIELDS: readonly ["getNum", "getA", "anum", "getText", "getB", "getC", "__a"];
|
|
25
42
|
}
|
|
26
|
-
declare function composeC(obj: _C): _C & Pick<B, "getText" | "getB"> &
|
|
43
|
+
declare function composeC(obj: _C): _C & Pick<B, "getText" | "getB"> & {
|
|
44
|
+
__b: B;
|
|
45
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
46
|
+
__a: A;
|
|
47
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
27
48
|
export type C = ReturnType<typeof composeC>;
|
|
28
49
|
export declare const C: typeof _C;
|
|
50
|
+
declare class _D {
|
|
51
|
+
#private;
|
|
52
|
+
private constructor();
|
|
53
|
+
static create(): _D & Pick<_C & Pick<B, "getText" | "getB"> & {
|
|
54
|
+
__b: B;
|
|
55
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
56
|
+
__a: A;
|
|
57
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">, "__a" | "anum" | "getNum" | "getA" | "getText" | "getB" | "getC"> & {
|
|
58
|
+
__c: _C & Pick<B, "getText" | "getB"> & {
|
|
59
|
+
__b: B;
|
|
60
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
61
|
+
__a: A;
|
|
62
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
63
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
64
|
+
}
|
|
65
|
+
declare function composeD(obj: _D): _D & Pick<_C & Pick<B, "getText" | "getB"> & {
|
|
66
|
+
__b: B;
|
|
67
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
68
|
+
__a: A;
|
|
69
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">, "__a" | "anum" | "getNum" | "getA" | "getText" | "getB" | "getC"> & {
|
|
70
|
+
__c: _C & Pick<B, "getText" | "getB"> & {
|
|
71
|
+
__b: B;
|
|
72
|
+
} & Pick<A, "anum" | "getNum" | "getA"> & {
|
|
73
|
+
__a: A;
|
|
74
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
75
|
+
} & Record<"bindFunc", () => "这是动态绑定的函数">;
|
|
76
|
+
export type D = ReturnType<typeof composeD>;
|
|
77
|
+
export declare const D: typeof _D;
|
|
29
78
|
export {};
|
package/dist/test/composeTest.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.C = void 0;
|
|
3
|
+
exports.D = exports.C = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
5
|
class A {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
anum = 1;
|
|
7
|
+
constructor(n = 1) { this.anum = n; }
|
|
8
|
+
getNum = () => this.anum;
|
|
8
9
|
/**A的函数 */
|
|
9
10
|
getA = () => this;
|
|
10
|
-
|
|
11
|
+
MIXIN_KEY = "__a";
|
|
12
|
+
static MIXIN_FIELDS = ['getNum', 'getA', 'anum'];
|
|
13
|
+
MIXIN_FIELDS = A.MIXIN_FIELDS;
|
|
11
14
|
}
|
|
12
15
|
class B {
|
|
13
16
|
text = "B的text";
|
|
@@ -20,7 +23,9 @@ class B {
|
|
|
20
23
|
privateFunc() {
|
|
21
24
|
console.log();
|
|
22
25
|
}
|
|
23
|
-
|
|
26
|
+
MIXIN_KEY = "__b";
|
|
27
|
+
static MIXIN_FIELDS = ['getText', 'getB'];
|
|
28
|
+
MIXIN_FIELDS = B.MIXIN_FIELDS;
|
|
24
29
|
}
|
|
25
30
|
class _C {
|
|
26
31
|
static create() {
|
|
@@ -35,6 +40,13 @@ class _C {
|
|
|
35
40
|
console.log(this);
|
|
36
41
|
return 2;
|
|
37
42
|
}
|
|
43
|
+
MIXIN_KEY = "__c";
|
|
44
|
+
static MIXIN_FIELDS = [
|
|
45
|
+
...A.MIXIN_FIELDS,
|
|
46
|
+
...B.MIXIN_FIELDS,
|
|
47
|
+
'getC', '__a'
|
|
48
|
+
];
|
|
49
|
+
MIXIN_FIELDS = exports.C.MIXIN_FIELDS;
|
|
38
50
|
}
|
|
39
51
|
function composeC(obj) {
|
|
40
52
|
let ob1 = __1.UtilFunc.composeMixinable(obj, new B(), new A());
|
|
@@ -42,10 +54,35 @@ function composeC(obj) {
|
|
|
42
54
|
return ob3;
|
|
43
55
|
}
|
|
44
56
|
exports.C = _C;
|
|
45
|
-
(0, __1.assertThisAs)(exports.C.prototype);
|
|
46
57
|
const insc = exports.C.create(); //?
|
|
58
|
+
console.log(insc.__a);
|
|
47
59
|
insc.getC().testFunc(); //?
|
|
60
|
+
insc.getNum(); //?
|
|
61
|
+
insc.anum; //?
|
|
62
|
+
insc.__a = new A(2);
|
|
63
|
+
insc.getNum(); //?
|
|
64
|
+
insc.anum; //?
|
|
48
65
|
insc.testFunc(); //?
|
|
49
66
|
insc.getText(); //?
|
|
50
67
|
insc.getB().getText(); //?
|
|
51
68
|
insc.bindFunc(); //?
|
|
69
|
+
class _D {
|
|
70
|
+
constructor() { }
|
|
71
|
+
;
|
|
72
|
+
static create() {
|
|
73
|
+
return composeD(new _D());
|
|
74
|
+
}
|
|
75
|
+
#d = 123;
|
|
76
|
+
}
|
|
77
|
+
function composeD(obj) {
|
|
78
|
+
let ob1 = __1.UtilFunc.composeMixinable(obj, exports.C.create());
|
|
79
|
+
let ob3 = __1.UtilFP.bindTo('bindFunc', () => "这是动态绑定的函数", ob1);
|
|
80
|
+
return ob3;
|
|
81
|
+
}
|
|
82
|
+
exports.D = _D;
|
|
83
|
+
let insd = exports.D.create();
|
|
84
|
+
insd; //?
|
|
85
|
+
insd.getB(); //?
|
|
86
|
+
insd.getNum(); //?
|
|
87
|
+
insd.__a = new A(3);
|
|
88
|
+
insd.getNum(); //?
|
package/dist/test/test.js
CHANGED
|
@@ -2,58 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const UtilFP_1 = require("../UtilFP");
|
|
4
4
|
const UtilFunctions_1 = require("../UtilFunctions");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
abc = 223;
|
|
8
|
-
/**A的getData */
|
|
9
|
-
getData() {
|
|
10
|
-
return this.abc;
|
|
11
|
-
}
|
|
12
|
-
/**获取A */
|
|
13
|
-
getA() {
|
|
14
|
-
return this;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
class C {
|
|
18
|
-
abc = 3333;
|
|
19
|
-
/**A的getData */
|
|
20
|
-
resetData() {
|
|
21
|
-
return this.abc;
|
|
22
|
-
}
|
|
23
|
-
/**获取C */
|
|
24
|
-
getC() {
|
|
25
|
-
return this;
|
|
26
|
-
}
|
|
27
|
-
/**获取C */
|
|
28
|
-
getC1() {
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
class B {
|
|
33
|
-
_bc;
|
|
34
|
-
constructor() {
|
|
35
|
-
const tb = this;
|
|
36
|
-
this._bc = UtilFunctions_1.UtilFunc.composeClassPart(tb, new A(), ...compKeys);
|
|
37
|
-
}
|
|
38
|
-
static init() {
|
|
39
|
-
return new B()._bc;
|
|
40
|
-
}
|
|
41
|
-
/**B的getData */
|
|
42
|
-
getData1() { return "BGetdata"; }
|
|
43
|
-
getTest() { return this._bc.getData(); }
|
|
44
|
-
}
|
|
45
|
-
const BComp = {
|
|
46
|
-
init() {
|
|
47
|
-
return B.init();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
let c = BComp.init();
|
|
51
|
-
console.log(1);
|
|
52
|
-
let d = c.getData(); //?
|
|
53
|
-
c.getA;
|
|
54
|
-
c.getData1(); //?
|
|
55
|
-
c.getTest(); //?
|
|
56
|
-
let r3 = null;
|
|
5
|
+
const backup_1 = require("../backup");
|
|
6
|
+
// 使用示例
|
|
57
7
|
class Monster {
|
|
58
8
|
constructor(a) { }
|
|
59
9
|
monfunc() {
|
|
@@ -74,7 +24,7 @@ const OtherMonster = {
|
|
|
74
24
|
let om = {
|
|
75
25
|
om: "123", mon
|
|
76
26
|
};
|
|
77
|
-
return
|
|
27
|
+
return (0, backup_1.composeClassFull)(om, mon, mon1);
|
|
78
28
|
}
|
|
79
29
|
};
|
|
80
30
|
let om = OtherMonster.init(); //?
|
package/package.json
CHANGED
package/src/UtilFP.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export namespace UtilFP {
|
|
4
4
|
|
|
5
5
|
/**柯里化函数类型 */
|
|
6
|
-
type CurryFunc<T, PrevArgs extends
|
|
6
|
+
type CurryFunc<T, PrevArgs extends unknown[] = []> = T extends (...args: infer Args) => infer Result
|
|
7
7
|
? Args extends [infer Arg, ...infer RestArgs]
|
|
8
8
|
? RestArgs extends []
|
|
9
9
|
? (...args: [...PrevArgs, Arg]) => Result
|
package/src/UtilFunctions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from "crypto";
|
|
2
|
-
import { ComposedClass,
|
|
2
|
+
import { ComposedClass, ComposedMixinable, FuncPropNames, JToken, Mixinable, PromiseProcFn, PromiseStat, PromiseVerifyFn } from "@src/UtilInterfaces";
|
|
3
3
|
import * as cp from "child_process";
|
|
4
4
|
import { SLogger } from "@src/UtilLogger";
|
|
5
5
|
|
|
@@ -217,89 +217,64 @@ export async function repeatPromise<T>(procFn:PromiseProcFn<T>,verifyFn?:Promise
|
|
|
217
217
|
* 将mixin的部分字段混入base
|
|
218
218
|
* @param base - 基础类
|
|
219
219
|
* @param mixin - 目标类
|
|
220
|
+
* @param key - mixin 对象在 base 中的 key
|
|
220
221
|
* @param fields - 需要混入的字段
|
|
221
222
|
* @returns 混合完成的类
|
|
222
223
|
*/
|
|
223
224
|
export function composeClassPart
|
|
224
225
|
<Base extends object,Mixin extends object,Field extends keyof Mixin>
|
|
225
|
-
(base:Base,mixin:Mixin,...fields:Field[]):
|
|
226
|
+
(base:Base,mixin:Mixin,key:string,...fields:Field[]):ComposedClass<Base,Mixin,typeof key,Field>{
|
|
226
227
|
const compObj = base as any;
|
|
228
|
+
compObj[key] = mixin;
|
|
227
229
|
for(const fd of fields){
|
|
228
|
-
|
|
230
|
+
if(compObj[fd]!==undefined)
|
|
231
|
+
SLogger.warn(`${fd as string} 已存在于基础类中, 混入可能导致类型问题, 如需覆盖, 请使用 ${key}=val`);
|
|
229
232
|
Object.defineProperty(compObj, fd, {
|
|
230
|
-
get: ()=>
|
|
231
|
-
set: (value)=>{
|
|
233
|
+
get: ()=>compObj[key][fd],
|
|
234
|
+
set: (value)=>{compObj[key][fd] = value},
|
|
232
235
|
enumerable:true ,
|
|
233
236
|
//writable: true ,
|
|
234
237
|
configurable: true
|
|
235
238
|
});
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
} else {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
239
|
+
//if(typeof mixin[fd] === 'function') {
|
|
240
|
+
// compObj[fd] = (...args: any[]) => compObj[key][fd](...args);
|
|
241
|
+
// //(compObj as any)[fd] = (...args: any[]) => (mixin[fd] as any).apply(mixin, args);
|
|
242
|
+
// //(compObj as any)[fd] = (mixin[fd] as any).bind(mixin);
|
|
243
|
+
//} else {
|
|
244
|
+
// Object.defineProperty(compObj, fd, {
|
|
245
|
+
// get: ()=>compObj[key][fd],
|
|
246
|
+
// set: (value)=>{compObj[key][fd] = value},
|
|
247
|
+
// enumerable:true ,
|
|
248
|
+
// //writable: true ,
|
|
249
|
+
// configurable: true
|
|
250
|
+
// });
|
|
251
|
+
//}
|
|
249
252
|
}
|
|
250
253
|
return compObj;
|
|
251
254
|
}
|
|
252
255
|
|
|
253
256
|
/**根据 MIXIN_FIELDS 自动混入 */
|
|
254
257
|
export function composeMixinable
|
|
255
|
-
<
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
ComposedMixinable<B,[M1,M2,M3,M4,M5,M6,M4,M8,M9]>
|
|
259
|
-
export function composeMixinable<Base extends object, Mixin extends Mixinable<Mixin>>(base:Base,...mixins:Mixin[]){
|
|
258
|
+
<Base extends object, Mixins extends Mixinable<any>[]>
|
|
259
|
+
(base:Base,...mixins:Mixins):
|
|
260
|
+
ComposedMixinable<Base,Mixins>{
|
|
260
261
|
let out = base;
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
* @returns - 混合完成的类
|
|
271
|
-
*/
|
|
272
|
-
export function composeClass<Base extends object,MixinList extends object[]>
|
|
273
|
-
(base:Base,...mixinList:MixinList):ComposedClassMult<Base,MixinList>{
|
|
274
|
-
let obj = base as any;
|
|
275
|
-
for(let mixin of mixinList as any){
|
|
276
|
-
let propks = Object.getOwnPropertyNames(mixin.constructor.prototype)
|
|
277
|
-
for(const key of propks){
|
|
278
|
-
if(key != "constructor"){
|
|
279
|
-
Object.defineProperty(obj, key, {
|
|
280
|
-
get: ()=>mixin[key],
|
|
281
|
-
set: (value)=>{mixin[key] = value},
|
|
282
|
-
enumerable:true,
|
|
283
|
-
//writable: true,
|
|
284
|
-
configurable: true
|
|
285
|
-
});
|
|
286
|
-
//obj[key] = (mixin as any)[key];
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
for(const key in mixin){
|
|
290
|
-
Object.defineProperty(obj, key, {
|
|
291
|
-
get: ()=>mixin[key],
|
|
292
|
-
set: (value)=>{mixin[key] = value},
|
|
293
|
-
enumerable:true ,
|
|
294
|
-
//writable: true ,
|
|
295
|
-
configurable: true
|
|
296
|
-
});
|
|
297
|
-
//obj[key] = (mixin as any)[key];
|
|
262
|
+
const fieldsSet = new Set<string>();
|
|
263
|
+
for(const rawmixin of mixins){
|
|
264
|
+
const mixin=rawmixin as any;
|
|
265
|
+
for(const field of mixin.MIXIN_FIELDS) {
|
|
266
|
+
const fixField = field as string;
|
|
267
|
+
if(fieldsSet.has(fixField))
|
|
268
|
+
SLogger.warn(`composeMixinable 出现了重复的 field: ${fixField} 可能会导致问题`);
|
|
269
|
+
else
|
|
270
|
+
fieldsSet.add(fixField);
|
|
298
271
|
}
|
|
272
|
+
out = composeClassPart(base,mixin,mixin.MIXIN_KEY,...mixin.MIXIN_FIELDS);
|
|
299
273
|
}
|
|
300
|
-
return
|
|
274
|
+
return out as any;
|
|
301
275
|
}
|
|
302
276
|
|
|
277
|
+
|
|
303
278
|
/**对对象的每个属性应用映射函数,并返回一个新的对象。
|
|
304
279
|
* @template T - 对象的类型
|
|
305
280
|
* @param obj - 要处理的对象
|
package/src/UtilInterfaces.ts
CHANGED
|
@@ -92,81 +92,25 @@ export type FuncPropNames<T> = {
|
|
|
92
92
|
* @template Mixin - 待混入的类
|
|
93
93
|
* @template PropKeys - 需要混入的成员key
|
|
94
94
|
*/
|
|
95
|
-
export type
|
|
96
|
-
Base & Pick<Mixin, PropKeys
|
|
97
|
-
|
|
98
|
-
/**组合的类 嵌套变体 */
|
|
99
|
-
export type ComposedPartClassMult<Base extends object,
|
|
100
|
-
Mixin1 extends object = {}, PropKeys1 extends keyof Mixin1 = keyof Mixin1,
|
|
101
|
-
Mixin2 extends object = {}, PropKeys2 extends keyof Mixin2 = keyof Mixin2,
|
|
102
|
-
Mixin3 extends object = {}, PropKeys3 extends keyof Mixin3 = keyof Mixin3,
|
|
103
|
-
Mixin4 extends object = {}, PropKeys4 extends keyof Mixin4 = keyof Mixin4,
|
|
104
|
-
Mixin5 extends object = {}, PropKeys5 extends keyof Mixin5 = keyof Mixin5,
|
|
105
|
-
Mixin6 extends object = {}, PropKeys6 extends keyof Mixin6 = keyof Mixin6> =
|
|
106
|
-
ComposedClassPart<ComposedClassPart<ComposedClassPart<
|
|
107
|
-
ComposedClassPart<ComposedClassPart<ComposedClassPart<
|
|
108
|
-
Base,
|
|
109
|
-
Mixin1,PropKeys1>,Mixin2,PropKeys2>,Mixin3,PropKeys3>,
|
|
110
|
-
Mixin4,PropKeys4>,Mixin5,PropKeys5>,Mixin6,PropKeys6>
|
|
111
|
-
|
|
112
|
-
/**递归多组合 仅单key有效 */
|
|
113
|
-
type ComposedClassOnceKey<Base extends object,Data extends [object,string][]> =
|
|
114
|
-
Data extends [[infer Mixin extends object, infer FuncKeys], ...infer Rest]
|
|
115
|
-
? FuncKeys extends FuncPropNames<Mixin>
|
|
116
|
-
? Rest extends [any, any][]
|
|
117
|
-
? ComposedClassOnceKey<ComposedClassPart<Base, Mixin, FuncKeys>,Rest>
|
|
118
|
-
: Base
|
|
119
|
-
: Base
|
|
120
|
-
: Base;
|
|
121
|
-
|
|
122
|
-
/**组合的类
|
|
123
|
-
* @template Base - 基类
|
|
124
|
-
* @template Mixin - 待混入的类
|
|
125
|
-
*/
|
|
126
|
-
export type ComposedClass<Base extends object,Mixin extends object> = Base&Mixin;
|
|
127
|
-
/**组合的类 多组合变体
|
|
128
|
-
* @template Base - 基类
|
|
129
|
-
* @template MixinList- 待混入的类型数组
|
|
130
|
-
*/
|
|
131
|
-
export type ComposedClassMult<Base extends object,MixinList extends object[]> =
|
|
132
|
-
MixinList extends [infer Mixin, ...infer Rest]
|
|
133
|
-
? Mixin extends object
|
|
134
|
-
? Rest extends object[]
|
|
135
|
-
? ComposedClassMult<ComposedClass<Base,Mixin>,Rest>
|
|
136
|
-
: Base
|
|
137
|
-
: Base
|
|
138
|
-
: Base;
|
|
139
|
-
|
|
140
|
-
/**将一个类型的所有方法的 `this` 参数改为 `T` 类型
|
|
141
|
-
* @template Methods - 待更改的函数表
|
|
142
|
-
* @template T - 目标this类型
|
|
143
|
-
*/
|
|
144
|
-
export type MethodsThisAs<Methods, T> = {
|
|
145
|
-
[K in keyof Methods]:
|
|
146
|
-
Methods[K] extends (...args: infer A) => infer R
|
|
147
|
-
? (this: T, ...args: A) => R
|
|
148
|
-
: Methods[K];
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
/**尝试断言一个类的原型
|
|
152
|
-
* 其所有函数的 this 都必须为某个类型
|
|
153
|
-
* assignThisAs<Self,T>(Self.prototype);
|
|
154
|
-
* @template Self - 类的类型
|
|
155
|
-
* @template T - 目标this类型
|
|
156
|
-
* @param prototype - 类的原型
|
|
157
|
-
*/
|
|
158
|
-
export function assertThisAs<Self,T>(prototype: MethodsThisAs<Self, T>) {}
|
|
95
|
+
export type ComposedClass<Base extends object, Mixin extends object, Key extends string, PropKeys extends keyof Mixin> =
|
|
96
|
+
Base & Pick<Mixin, PropKeys> & {[P in Key]:Mixin};
|
|
159
97
|
|
|
160
98
|
/**可自动混入的类型 */
|
|
161
99
|
export type Mixinable<Mixin> = {
|
|
162
|
-
|
|
163
|
-
|
|
100
|
+
/**混入时自身所在位置
|
|
101
|
+
* 请使用字面量
|
|
102
|
+
*/
|
|
103
|
+
readonly MIXIN_KEY: string;
|
|
104
|
+
/**可混入的字段
|
|
105
|
+
* 请使用字面量
|
|
106
|
+
*/
|
|
107
|
+
readonly MIXIN_FIELDS: readonly (keyof Mixin)[];
|
|
164
108
|
};
|
|
165
109
|
|
|
166
110
|
/**自动组合可混入的类 */
|
|
167
|
-
export type ComposedMixinable<B extends object, Ms extends
|
|
111
|
+
export type ComposedMixinable<B extends object, Ms extends unknown[]> =
|
|
168
112
|
Ms extends [infer M, ...infer Rest]
|
|
169
113
|
? M extends Mixinable<M>
|
|
170
|
-
? ComposedMixinable<
|
|
171
|
-
:
|
|
114
|
+
? ComposedMixinable<ComposedClass<B,M,M['MIXIN_KEY'],M['MIXIN_FIELDS'][number]>,Rest>
|
|
115
|
+
: "一个混入类没有实现 Mixinable<self>" & Error
|
|
172
116
|
: B
|
package/src/backup.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { ComposedClass, FuncPropNames } from "./UtilInterfaces";
|
|
2
|
+
|
|
3
|
+
/**类组合
|
|
4
|
+
* 将mixinList每个成员的字段混入base
|
|
5
|
+
* @param base - 基础类
|
|
6
|
+
* @param mixinList - 目标类
|
|
7
|
+
* @returns - 混合完成的类
|
|
8
|
+
*/
|
|
9
|
+
export function composeClassFull<Base extends object,MixinList extends object[]>
|
|
10
|
+
(base:Base,...mixinList:MixinList):ComposedFullClassMult<Base,MixinList>{
|
|
11
|
+
let obj = base as any;
|
|
12
|
+
for(let mixin of mixinList as any){
|
|
13
|
+
let propks = Object.getOwnPropertyNames(mixin.constructor.prototype)
|
|
14
|
+
for(const key of propks){
|
|
15
|
+
if(key != "constructor"){
|
|
16
|
+
Object.defineProperty(obj, key, {
|
|
17
|
+
get: ()=>mixin[key],
|
|
18
|
+
set: (value)=>{mixin[key] = value},
|
|
19
|
+
enumerable:true,
|
|
20
|
+
//writable: true,
|
|
21
|
+
configurable: true
|
|
22
|
+
});
|
|
23
|
+
//obj[key] = (mixin as any)[key];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for(const key in mixin){
|
|
27
|
+
Object.defineProperty(obj, key, {
|
|
28
|
+
get: ()=>mixin[key],
|
|
29
|
+
set: (value)=>{mixin[key] = value},
|
|
30
|
+
enumerable:true ,
|
|
31
|
+
//writable: true ,
|
|
32
|
+
configurable: true
|
|
33
|
+
});
|
|
34
|
+
//obj[key] = (mixin as any)[key];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return obj;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
///**组合的类 嵌套变体 */
|
|
41
|
+
//export type ComposedClassMult<Base extends object,
|
|
42
|
+
// Mixin1 extends object = {}, PropKeys1 extends keyof Mixin1 = keyof Mixin1,
|
|
43
|
+
// Mixin2 extends object = {}, PropKeys2 extends keyof Mixin2 = keyof Mixin2,
|
|
44
|
+
// Mixin3 extends object = {}, PropKeys3 extends keyof Mixin3 = keyof Mixin3,
|
|
45
|
+
// Mixin4 extends object = {}, PropKeys4 extends keyof Mixin4 = keyof Mixin4,
|
|
46
|
+
// Mixin5 extends object = {}, PropKeys5 extends keyof Mixin5 = keyof Mixin5,
|
|
47
|
+
// Mixin6 extends object = {}, PropKeys6 extends keyof Mixin6 = keyof Mixin6> =
|
|
48
|
+
// ComposedClass<ComposedClass<ComposedClass<
|
|
49
|
+
// ComposedClass<ComposedClass<ComposedClass<
|
|
50
|
+
// Base,
|
|
51
|
+
// Mixin1,PropKeys1>,Mixin2,PropKeys2>,Mixin3,PropKeys3>,
|
|
52
|
+
// Mixin4,PropKeys4>,Mixin5,PropKeys5>,Mixin6,PropKeys6>
|
|
53
|
+
//
|
|
54
|
+
///**递归多组合 仅单key有效 */
|
|
55
|
+
//type ComposedClassOnceKey<Base extends object,Data extends [object,string][]> =
|
|
56
|
+
// Data extends [[infer Mixin extends object, infer FuncKeys], ...infer Rest]
|
|
57
|
+
// ? FuncKeys extends FuncPropNames<Mixin>
|
|
58
|
+
// ? Rest extends [any, any][]
|
|
59
|
+
// ? ComposedClassOnceKey<ComposedClass<Base, Mixin, FuncKeys>,Rest>
|
|
60
|
+
// : Base
|
|
61
|
+
// : Base
|
|
62
|
+
// : Base;
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
/**组合的类
|
|
67
|
+
* @template Base - 基类
|
|
68
|
+
* @template Mixin - 待混入的类
|
|
69
|
+
*/
|
|
70
|
+
export type ComposedFullClass<Base extends object,Mixin extends object> = Base&Mixin;
|
|
71
|
+
/**组合的类 多组合变体
|
|
72
|
+
* @template Base - 基类
|
|
73
|
+
* @template MixinList- 待混入的类型数组
|
|
74
|
+
*/
|
|
75
|
+
export type ComposedFullClassMult<Base extends object,MixinList extends object[]> =
|
|
76
|
+
MixinList extends [infer Mixin, ...infer Rest]
|
|
77
|
+
? Mixin extends object
|
|
78
|
+
? Rest extends object[]
|
|
79
|
+
? ComposedFullClassMult<ComposedFullClass<Base,Mixin>,Rest>
|
|
80
|
+
: Base
|
|
81
|
+
: Base
|
|
82
|
+
: Base;
|
|
83
|
+
|
|
84
|
+
/**将一个类型的所有方法的 `this` 参数改为 `T` 类型
|
|
85
|
+
* @template Methods - 待更改的函数表
|
|
86
|
+
* @template T - 目标this类型
|
|
87
|
+
*/
|
|
88
|
+
export type MethodsThisAs<Methods, T> = {
|
|
89
|
+
[K in keyof Methods]:
|
|
90
|
+
Methods[K] extends (...args: infer A) => infer R
|
|
91
|
+
? (this: T, ...args: A) => R
|
|
92
|
+
: Methods[K];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/**尝试断言一个类的原型
|
|
96
|
+
* 其所有函数的 this 都必须为某个类型
|
|
97
|
+
* assignThisAs<Self,T>(Self.prototype);
|
|
98
|
+
* @template Self - 类的类型
|
|
99
|
+
* @template T - 目标this类型
|
|
100
|
+
* @param prototype - 类的原型
|
|
101
|
+
*/
|
|
102
|
+
export function assertThisAs<Self,T>(prototype: MethodsThisAs<Self, T>) {}
|
package/src/test/composeTest.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { assertThisAs } from "@src/backup";
|
|
2
|
+
import { Mixinable, UtilFP, UtilFunc } from ".."
|
|
3
|
+
import { Writable } from "stream";
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
type MixinA = Mixinable<A>;
|
|
6
|
+
class A implements MixinA{
|
|
7
|
+
anum = 1;
|
|
8
|
+
constructor(n=1){this.anum=n}
|
|
9
|
+
getNum = ()=>this.anum;
|
|
6
10
|
/**A的函数 */
|
|
7
11
|
getA=()=>this;
|
|
8
|
-
|
|
12
|
+
readonly MIXIN_KEY = "__a" as const;
|
|
13
|
+
static MIXIN_FIELDS = ['getNum','getA','anum'] as const;
|
|
14
|
+
readonly MIXIN_FIELDS = A.MIXIN_FIELDS;
|
|
9
15
|
}
|
|
10
16
|
class B implements Mixinable<B>{
|
|
11
17
|
private text = "B的text";
|
|
@@ -18,7 +24,9 @@ class B implements Mixinable<B>{
|
|
|
18
24
|
privateFunc(){
|
|
19
25
|
console.log()
|
|
20
26
|
}
|
|
21
|
-
|
|
27
|
+
readonly MIXIN_KEY = "__b" as const;
|
|
28
|
+
static readonly MIXIN_FIELDS = ['getText','getB'] as const;
|
|
29
|
+
readonly MIXIN_FIELDS = B.MIXIN_FIELDS;
|
|
22
30
|
}
|
|
23
31
|
class _C {
|
|
24
32
|
static create(){
|
|
@@ -32,6 +40,13 @@ class _C {
|
|
|
32
40
|
console.log(this);
|
|
33
41
|
return 2;
|
|
34
42
|
}
|
|
43
|
+
readonly MIXIN_KEY = "__c" as const;
|
|
44
|
+
static readonly MIXIN_FIELDS = [
|
|
45
|
+
...A.MIXIN_FIELDS,
|
|
46
|
+
...B.MIXIN_FIELDS,
|
|
47
|
+
'getC','__a'
|
|
48
|
+
] as const;
|
|
49
|
+
readonly MIXIN_FIELDS = C.MIXIN_FIELDS;
|
|
35
50
|
}
|
|
36
51
|
function composeC(obj:_C){
|
|
37
52
|
let ob1 = UtilFunc.composeMixinable(obj,new B(),new A());
|
|
@@ -40,12 +55,39 @@ function composeC(obj:_C){
|
|
|
40
55
|
}
|
|
41
56
|
export type C = ReturnType<typeof composeC>;
|
|
42
57
|
export const C = _C;
|
|
43
|
-
assertThisAs<_C,C>(C.prototype);
|
|
44
58
|
|
|
45
59
|
const insc:C=C.create();//?
|
|
60
|
+
console.log(insc.__a)
|
|
46
61
|
insc.getC().testFunc()//?
|
|
62
|
+
insc.getNum()//?
|
|
63
|
+
insc.anum//?
|
|
64
|
+
insc.__a = new A(2);
|
|
65
|
+
insc.getNum()//?
|
|
66
|
+
insc.anum//?
|
|
47
67
|
insc.testFunc();//?
|
|
48
68
|
insc.getText();//?
|
|
49
69
|
insc.getB().getText()//?
|
|
50
70
|
insc.bindFunc()//?
|
|
51
71
|
|
|
72
|
+
class _D{
|
|
73
|
+
private constructor(){};
|
|
74
|
+
static create(){
|
|
75
|
+
return composeD(new _D());
|
|
76
|
+
}
|
|
77
|
+
#d = 123;
|
|
78
|
+
}
|
|
79
|
+
function composeD(obj:_D){
|
|
80
|
+
let ob1 = UtilFunc.composeMixinable(obj,C.create());
|
|
81
|
+
let ob3 = UtilFP.bindTo('bindFunc',()=>"这是动态绑定的函数",ob1);
|
|
82
|
+
return ob3;
|
|
83
|
+
}
|
|
84
|
+
export type D = ReturnType<typeof composeD>;
|
|
85
|
+
export const D = _D;
|
|
86
|
+
|
|
87
|
+
let insd:D = D.create();
|
|
88
|
+
insd//?
|
|
89
|
+
insd.getB()//?
|
|
90
|
+
insd.getNum()//?
|
|
91
|
+
insd.__a = new A(3);
|
|
92
|
+
insd.getNum()//?
|
|
93
|
+
|
package/src/test/test.ts
CHANGED
|
@@ -1,68 +1,10 @@
|
|
|
1
1
|
import { UtilFP } from "@src/UtilFP";
|
|
2
2
|
import { UtilFunc } from "@src/UtilFunctions";
|
|
3
|
-
import {
|
|
3
|
+
import { ComposedClass, FixedLengthTuple, FuncPropNames } from "@src/UtilInterfaces";
|
|
4
|
+
import { ComposedFullClassMult, composeClassFull } from "@src/backup";
|
|
4
5
|
|
|
5
|
-
const compKeys = ["getData","getA"] as const;
|
|
6
|
-
|
|
7
|
-
class A {
|
|
8
|
-
abc=223;
|
|
9
|
-
/**A的getData */
|
|
10
|
-
getData(){
|
|
11
|
-
return this.abc
|
|
12
|
-
}
|
|
13
|
-
/**获取A */
|
|
14
|
-
getA(){
|
|
15
|
-
return this;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
class C {
|
|
19
|
-
abc=3333;
|
|
20
|
-
/**A的getData */
|
|
21
|
-
resetData(){
|
|
22
|
-
return this.abc
|
|
23
|
-
}
|
|
24
|
-
/**获取C */
|
|
25
|
-
getC(){
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
/**获取C */
|
|
29
|
-
private getC1(){
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
class B{
|
|
34
|
-
private _bc:BComp;
|
|
35
|
-
private constructor(){
|
|
36
|
-
const tb:B = this;
|
|
37
|
-
this._bc = UtilFunc.composeClassPart(tb, new A(), ...compKeys);
|
|
38
|
-
}
|
|
39
|
-
static init(){
|
|
40
|
-
return new B()._bc;
|
|
41
|
-
}
|
|
42
|
-
/**B的getData */
|
|
43
|
-
getData1(){return "BGetdata"}
|
|
44
|
-
getTest(){return this._bc.getData()}
|
|
45
|
-
}
|
|
46
|
-
type BComp = ComposedClassPart<B, A, typeof compKeys[number]>;
|
|
47
|
-
const BComp = {
|
|
48
|
-
init(){
|
|
49
|
-
return B.init();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let c:BComp = BComp.init();
|
|
54
|
-
console.log(1);
|
|
55
|
-
let d = c.getData();//?
|
|
56
|
-
c.getA
|
|
57
|
-
c.getData1();//?
|
|
58
|
-
c.getTest();//?
|
|
59
6
|
|
|
60
7
|
// 使用示例
|
|
61
|
-
type R3 = ComposedPartClassMult<B, A, "getData"|"getA", C>
|
|
62
|
-
let r3:R3 = null as any;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
8
|
class Monster{
|
|
67
9
|
constructor(a:number){}
|
|
68
10
|
monfunc(){
|
|
@@ -76,18 +18,18 @@ class Monster1{
|
|
|
76
18
|
return "mon1"
|
|
77
19
|
}
|
|
78
20
|
}
|
|
79
|
-
type OtherMonster =
|
|
21
|
+
type OtherMonster = ComposedFullClassMult<{
|
|
80
22
|
om:string
|
|
81
23
|
mon:Monster
|
|
82
24
|
},[Monster,Monster1]>
|
|
83
25
|
const OtherMonster = {
|
|
84
|
-
init()
|
|
26
|
+
init(){
|
|
85
27
|
let mon = new Monster(123);
|
|
86
28
|
let mon1 = new Monster1(223);
|
|
87
29
|
let om = {
|
|
88
30
|
om:"123",mon
|
|
89
31
|
}
|
|
90
|
-
return
|
|
32
|
+
return composeClassFull(om,mon,mon1);
|
|
91
33
|
}
|
|
92
34
|
}
|
|
93
35
|
|