annil 1.6.1 → 1.6.3
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 +14 -0
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/computedUpdater.js +4 -4
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/computedUpdater.js.map +1 -1
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/data-tracer.d.ts +3 -0
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/data-tracer.js +16 -8
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/data-tracer.js.map +1 -1
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/index.js +2 -2
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/index.js.map +1 -1
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/initComputedAndGetCache.d.ts +12 -0
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/{initComputed.js → initComputedAndGetCache.js} +17 -26
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/initComputedAndGetCache.js.map +1 -0
- package/dist/api/DefineComponent/assignOptions/index.d.ts +1 -1
- package/dist/api/DefineComponent/assignOptions/index.js +0 -8
- package/dist/api/DefineComponent/assignOptions/index.js.map +1 -1
- package/dist/api/InstanceInject/instanceConfig.d.ts +5 -2
- package/dist/api/InstanceInject/instanceConfig.js.map +1 -1
- package/dist/api/RootComponent/Instance/RootComponentInstance.d.ts +3 -6
- package/dist/api/RootComponent/Observers/ObserversOption.d.ts +2 -3
- package/dist/api/RootComponent/Watch/WatchOption.d.ts +2 -3
- package/dist/api/RootComponent/index.d.ts +2 -2
- package/package.json +1 -1
- package/src/api/DefineComponent/assignOptions/computedWatchHandle/computedUpdater.ts +5 -4
- package/src/api/DefineComponent/assignOptions/computedWatchHandle/data-tracer.ts +20 -16
- package/src/api/DefineComponent/assignOptions/computedWatchHandle/index.ts +9 -5
- package/src/api/DefineComponent/assignOptions/computedWatchHandle/{initComputed.ts → initComputedAndGetCache.ts} +38 -57
- package/src/api/DefineComponent/assignOptions/index.ts +13 -13
- package/src/api/InstanceInject/instanceConfig.ts +11 -2
- package/src/api/RootComponent/Computed/test/normal.test.ts +16 -16
- package/src/api/RootComponent/CustomEvents/test/normal.test.ts +0 -19
- package/src/api/RootComponent/Data/test/normal.test.ts +5 -36
- package/src/api/RootComponent/Instance/RootComponentInstance.ts +4 -5
- package/src/api/RootComponent/Instance/test/properties/mormal.test.ts +9 -4
- package/src/api/RootComponent/Observers/ObserversOption.ts +8 -11
- package/src/api/RootComponent/Observers/test/normal.test.ts +2 -3
- package/src/api/RootComponent/Properties/test/normalEmpty.test.ts +5 -6
- package/src/api/RootComponent/Properties/test/normalOptional.test.ts +4 -4
- package/src/api/RootComponent/Properties/test/normalRequired.test.ts +4 -4
- package/src/api/RootComponent/Watch/WatchOption.ts +17 -23
- package/src/api/RootComponent/Watch/test/WatchComputed.test.ts +4 -4
- package/src/api/RootComponent/Watch/test/WatchData.test.ts +4 -5
- package/src/api/RootComponent/Watch/test/WatchProperties.test.ts +13 -23
- package/src/api/RootComponent/index.ts +2 -2
- package/src/api/SubComponent/SubComputed/test/normal.test.ts +6 -6
- package/src/api/SubComponent/SubData/test/normal.test.ts +5 -5
- package/src/api/SubComponent/SubInstance/test/normal.test.ts +4 -4
- package/src/api/SubComponent/SubWatch/test/WatchProperties.test.ts +13 -23
- package/src/api/SubComponent/SubWatch/test/WatchRootData.test.ts +10 -11
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/initComputed.d.ts +0 -12
- package/dist/api/DefineComponent/assignOptions/computedWatchHandle/initComputed.js.map +0 -1
- package/src/api/RootComponent/Instance/test/cloneData/error.test.ts +0 -31
- package/src/api/RootComponent/Instance/test/cloneData/normal.test.ts +0 -53
- package/src/api/SubComponent/SubInstance/test/cloneData/error.test.ts +0 -22
- package/src/api/SubComponent/SubInstance/test/cloneData/normal.test.ts +0 -73
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { Func } from "hry-types/src/Misc/Func";
|
|
2
2
|
import type { FinalOptionsOfComponent } from "..";
|
|
3
3
|
|
|
4
|
-
import { deepClone } from "../../../../utils/deepClone";
|
|
5
4
|
import type { ComputedDependence } from "./computedUpdater";
|
|
6
|
-
import { deepProxy } from "./data-tracer";
|
|
5
|
+
import { deepProxy, getProxyOriginalValue } from "./data-tracer";
|
|
7
6
|
|
|
8
7
|
type ItemCache = {
|
|
9
8
|
dependences: ComputedDependence[];
|
|
@@ -11,45 +10,22 @@ type ItemCache = {
|
|
|
11
10
|
value: unknown;
|
|
12
11
|
};
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
type ComputedId = string;
|
|
14
|
+
|
|
15
|
+
export type ComputedCache = Record<ComputedId, ItemCache>;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
|
-
* 如果依赖列表某项的首个字段值为undefined并且字段为其他计算属性字段 返回false(即被依赖的计算字段写在了依赖他的计算字段后面), 否则返回
|
|
18
|
+
* 如果依赖列表某项的首个字段值为undefined并且字段为其他计算属性字段 返回false(即被依赖的计算字段写在了依赖他的计算字段后面), 否则返回true表示依赖有效。
|
|
18
19
|
*/
|
|
19
20
|
function isValidDependences(dependences: ComputedDependence[], computedKeys: string[]): boolean {
|
|
20
21
|
for (const { paths: path, val } of dependences) {
|
|
21
|
-
// 引用值为undefined时
|
|
22
|
-
// console.log(path[0]);
|
|
23
22
|
if ((val === undefined) && computedKeys.includes(path[0])) {
|
|
24
23
|
return false;
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export function getItemCache(
|
|
32
|
-
initAllData: object,
|
|
33
|
-
computedKeys: string[],
|
|
34
|
-
computedFunc: Func,
|
|
35
|
-
): false | ItemCache {
|
|
36
|
-
// 当前计算字段的依赖列表
|
|
37
|
-
const dependences: ComputedDependence[] = [];
|
|
38
|
-
const initValue = computedFunc.call({ data: deepProxy(initAllData, dependences) });
|
|
39
|
-
|
|
40
|
-
if (isValidDependences(dependences, computedKeys)) {
|
|
41
|
-
return {
|
|
42
|
-
// 去重 避免 如: ` age(){ return this.data.xxx.num + this.data.xxx.str + this.data.xxx} ` 造成的多个依赖相同情况。应就要一个 xxx
|
|
43
|
-
dependences: uniqueDependences(dependences),
|
|
44
|
-
method: computedFunc,
|
|
45
|
-
value: deepClone(initValue),
|
|
46
|
-
};
|
|
47
|
-
} else {
|
|
48
|
-
/**
|
|
49
|
-
* 情形1 依赖了其他未初始化的计算属性(不报错) 对应测试文件[NoOptionalProperties.ts](../../../jest/computed/NoOptionalProperties/NoOptionalProperties.test.ts)的copyPropUser字段
|
|
50
|
-
*/
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
27
|
+
// 依赖有效
|
|
28
|
+
return true;
|
|
53
29
|
}
|
|
54
30
|
|
|
55
31
|
/**
|
|
@@ -63,24 +39,17 @@ export function getItemCache(
|
|
|
63
39
|
*/
|
|
64
40
|
function uniqueDependences(dependences: ComputedDependence[]): ComputedDependence[] {
|
|
65
41
|
if (dependences.length === 1) return dependences;
|
|
66
|
-
// console.log(dependences);
|
|
67
|
-
|
|
68
42
|
for (let f = 0; f < dependences.length; f++) {
|
|
69
43
|
const firstPath = dependences[f].paths.join(".") + ".";
|
|
70
44
|
for (let i = f + 1; i < dependences.length; i++) {
|
|
71
45
|
const curPath = dependences[i].paths.join(".") + ".";
|
|
72
|
-
// console.log(firstPath,curPath)
|
|
73
46
|
if (firstPath.startsWith(curPath)) {
|
|
74
|
-
// console.log("删除:", curPath, f);
|
|
75
|
-
|
|
76
47
|
// 例如 path[0] = 'a.b.c.',curPath = 'a.b.'
|
|
77
48
|
dependences.splice(f, 1);
|
|
78
49
|
|
|
79
50
|
return uniqueDependences(dependences);
|
|
80
51
|
}
|
|
81
52
|
if (curPath.startsWith(firstPath)) {
|
|
82
|
-
// console.log("删除:", firstPath, i);
|
|
83
|
-
|
|
84
53
|
// 例如 curPath = 'a.b.' path[0] = 'a.b.c.',
|
|
85
54
|
dependences.splice(i, 1);
|
|
86
55
|
|
|
@@ -93,43 +62,55 @@ function uniqueDependences(dependences: ComputedDependence[]): ComputedDependenc
|
|
|
93
62
|
}
|
|
94
63
|
|
|
95
64
|
/**
|
|
96
|
-
* 把计算属性初始值加入到options.data
|
|
65
|
+
* 把计算属性初始值加入到options.data中并返回缓存(递归函数)
|
|
66
|
+
* @param options - 配置选项
|
|
67
|
+
* @param computedConfig - 计算字段配置
|
|
68
|
+
* @param initAllData - 初始化时全部的data包含(properties,data,和已经初始化后的computed字段)
|
|
69
|
+
* @param uninitedkeys - 未初始化的key (默认为所有computedConfig的key)
|
|
70
|
+
* @param computedCache - 返回的所有计算字段缓存(默认为空对象)
|
|
71
|
+
* @returns `computedCache` 计算字段缓存
|
|
97
72
|
*/
|
|
98
|
-
export function
|
|
73
|
+
export function initComputedAndGetCache(
|
|
99
74
|
options: FinalOptionsOfComponent,
|
|
100
75
|
computedConfig: Record<string, Func>,
|
|
101
|
-
initAllData:
|
|
76
|
+
initAllData: Record<string, unknown>,
|
|
102
77
|
uninitedkeys: string[] = Object.keys(computedConfig),
|
|
103
78
|
computedCache: ComputedCache = {},
|
|
104
79
|
): ComputedCache {
|
|
105
|
-
// 收集依赖 uninitedkeys不受内部2处重新赋值的影响
|
|
106
|
-
|
|
107
80
|
for (const key of uninitedkeys) {
|
|
108
|
-
|
|
109
|
-
const
|
|
81
|
+
const computedFunc = computedConfig[key];
|
|
82
|
+
const dependences: ComputedDependence[] = [];
|
|
83
|
+
// 通过代理data获取计算字段的初始值和依赖
|
|
84
|
+
let initValue = computedFunc.call({ data: deepProxy(initAllData, dependences) });
|
|
110
85
|
|
|
111
|
-
//
|
|
86
|
+
// 去除当前已初始的计算属性key
|
|
112
87
|
uninitedkeys = uninitedkeys.filter(ele => ele !== key);
|
|
113
88
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
} else {
|
|
118
|
-
const dataOpt = options.data;
|
|
89
|
+
// 验证依赖是否有效
|
|
90
|
+
if (isValidDependences(dependences, uninitedkeys)) {
|
|
91
|
+
initValue = getProxyOriginalValue(initValue);
|
|
119
92
|
|
|
120
|
-
|
|
93
|
+
// 把计算属性初始值加入到options.data中
|
|
94
|
+
options.data[key] = initValue;
|
|
121
95
|
|
|
122
|
-
//
|
|
123
|
-
initAllData[key] =
|
|
96
|
+
// 把计算属性初始值加入到initAllData中,后续其他计算属性依赖时会可能会用到
|
|
97
|
+
initAllData[key] = initValue;
|
|
124
98
|
|
|
125
|
-
computedCache[key] =
|
|
99
|
+
computedCache[key] = {
|
|
100
|
+
dependences: uniqueDependences(dependences),
|
|
101
|
+
method: computedFunc,
|
|
102
|
+
value: initValue,
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
// 把当前依赖不正确的key放到后面去
|
|
106
|
+
uninitedkeys.push(key);
|
|
126
107
|
}
|
|
127
108
|
}
|
|
128
|
-
// 看uninitedkey
|
|
109
|
+
// 看uninitedkey是否未空,空表示所有依赖收集完毕直接返回
|
|
129
110
|
if (uninitedkeys.length === 0) {
|
|
130
111
|
return computedCache;
|
|
131
112
|
}
|
|
132
113
|
|
|
133
114
|
// uninitedkey不为空,递归
|
|
134
|
-
return
|
|
115
|
+
return initComputedAndGetCache(options, computedConfig, initAllData, uninitedkeys, computedCache);
|
|
135
116
|
}
|
|
@@ -27,7 +27,7 @@ import type { DefineComponentOption } from "..";
|
|
|
27
27
|
import { BStore } from "../../../behaviors/BStore";
|
|
28
28
|
import { computedWatchHandle } from "./computedWatchHandle";
|
|
29
29
|
|
|
30
|
-
import type { ComputedCache } from "./computedWatchHandle/
|
|
30
|
+
import type { ComputedCache } from "./computedWatchHandle/initComputedAndGetCache";
|
|
31
31
|
import { initStore } from "./initStore";
|
|
32
32
|
|
|
33
33
|
type InstanceInnerFields = {
|
|
@@ -101,13 +101,13 @@ export function isPageCheck(isPage: boolean | undefined) {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
function addCloneDataToInstance(this: Instance) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
104
|
+
// function addCloneDataToInstance(this: Instance) {
|
|
105
|
+
// this.cloneData = new Proxy(this.data, {
|
|
106
|
+
// get: <T extends object>(target: T, key: keyof T) => {
|
|
107
|
+
// return deepClone(target)[key];
|
|
108
|
+
// },
|
|
109
|
+
// });
|
|
110
|
+
// }
|
|
111
111
|
/**
|
|
112
112
|
* 原生Component会对传入的对象字段匹配的properties字段setData赋值。不符合字段或Page时不会赋值。
|
|
113
113
|
* 此函数为给实例setData赋值,默认传递值与properties相符(ts类型安全)。
|
|
@@ -446,11 +446,11 @@ export function assignOptions(
|
|
|
446
446
|
[isPageCheck(rootComponentOption?.isPage)],
|
|
447
447
|
);
|
|
448
448
|
|
|
449
|
-
hijack(
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
);
|
|
449
|
+
// hijack(
|
|
450
|
+
// finalOptionsForComponent.lifetimes!,
|
|
451
|
+
// "created",
|
|
452
|
+
// [addCloneDataToInstance],
|
|
453
|
+
// );
|
|
454
454
|
|
|
455
455
|
// 页面时删除预设的虚拟组件字段
|
|
456
456
|
finalOptionsForComponent.isPage
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/explicit-member-accessibility */
|
|
2
2
|
|
|
3
|
+
import type { IfEquals } from "hry-types/src/Any/IfEquals";
|
|
4
|
+
import type { ComputeIntersection } from "hry-types/src/Object/ComputeIntersection";
|
|
3
5
|
import type { ReturnTypeInObject } from "hry-types/src/Object/ReturnTypeInObject";
|
|
4
6
|
import type { WMComponentOption } from "../../types/OfficialTypeAlias";
|
|
5
7
|
import type { DataConstraint } from "../RootComponent/Data/DataConstraint";
|
|
@@ -19,9 +21,16 @@ interface BaseInjectInfo {
|
|
|
19
21
|
export interface IInjectInfo extends BaseInjectInfo {
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
export type
|
|
24
|
+
export type IInjectAllData = IfEquals<
|
|
25
|
+
{},
|
|
26
|
+
injectData & IInjectStore,
|
|
27
|
+
{},
|
|
28
|
+
ComputeIntersection<injectData & IInjectStore>
|
|
29
|
+
>;
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
type injectData = DataConstraint extends IInjectInfo["data"] ? {} : IInjectInfo["data"];
|
|
32
|
+
|
|
33
|
+
export type IInjectStore = StoreConstraint extends IInjectInfo["store"] ? {}
|
|
25
34
|
: ReturnTypeInObject<IInjectInfo["store"]>;
|
|
26
35
|
|
|
27
36
|
export type IInjectMethods = IInjectInfo["methods"];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { ComputeIntersection } from "hry-types/src/Object/_api";
|
|
3
|
+
import type { IInjectAllData } from "../../../InstanceInject/instanceConfig";
|
|
4
4
|
import { RootComponent } from "../..";
|
|
5
5
|
import type { Mock_User } from "../../Properties/test/normalRequired.test";
|
|
6
6
|
|
|
@@ -31,18 +31,18 @@ const RootDoc = RootComponent()({
|
|
|
31
31
|
// 3 this.data 类型是深度只读的
|
|
32
32
|
Checking<
|
|
33
33
|
typeof this.data,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
ComputeIntersection<
|
|
35
|
+
{
|
|
36
|
+
firstName: string;
|
|
37
|
+
lastName: string;
|
|
38
|
+
mock_User: Mock_User;
|
|
39
|
+
fullName: string;
|
|
40
|
+
user: Mock_User;
|
|
41
|
+
prefix: string;
|
|
42
|
+
id_fullName: string;
|
|
43
|
+
readOnly: "str";
|
|
44
|
+
} & IInjectAllData
|
|
45
|
+
>,
|
|
46
46
|
Test.Pass
|
|
47
47
|
>;
|
|
48
48
|
|
|
@@ -71,7 +71,7 @@ const noComputedFieldDoc = RootComponent()({
|
|
|
71
71
|
methods: {
|
|
72
72
|
M1() {
|
|
73
73
|
// 5.1 无computed,this.data中为{}
|
|
74
|
-
Checking<typeof this.data,
|
|
74
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
75
75
|
},
|
|
76
76
|
},
|
|
77
77
|
});
|
|
@@ -86,7 +86,7 @@ const EmptyComputedFieldDoc = RootComponent()({
|
|
|
86
86
|
methods: {
|
|
87
87
|
M1() {
|
|
88
88
|
// 6.1 computed为{},this.data中为{}
|
|
89
|
-
Checking<typeof this.data,
|
|
89
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
90
90
|
},
|
|
91
91
|
},
|
|
92
92
|
});
|
|
@@ -95,22 +95,3 @@ const rootDocNoFields = RootComponent()({});
|
|
|
95
95
|
|
|
96
96
|
// 3. 无customEvents字段时,Doc中无customEvents字段
|
|
97
97
|
Checking<typeof rootDocNoFields, {}, Test.Pass>;
|
|
98
|
-
|
|
99
|
-
// 4 实例中的对象数组都是readOnlyDeep类型,可以传递给自定义做参数
|
|
100
|
-
RootComponent()({
|
|
101
|
-
properties: {
|
|
102
|
-
obj: Object as DetailedType<Mock_User>,
|
|
103
|
-
},
|
|
104
|
-
data: {
|
|
105
|
-
obj1: {} as Mock_User,
|
|
106
|
-
_ddd: {} as Mock_User,
|
|
107
|
-
},
|
|
108
|
-
customEvents: mock_customEvents,
|
|
109
|
-
events: {
|
|
110
|
-
ddd() {
|
|
111
|
-
this.obj(this.data.obj!);
|
|
112
|
-
|
|
113
|
-
this.obj(this.data.obj1);
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
});
|
|
@@ -1,45 +1,14 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
|
|
3
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
4
|
-
import type { IInjectData } from "../../../InstanceInject/instanceConfig";
|
|
2
|
+
import type { IInjectAllData } from "../../../InstanceInject/instanceConfig";
|
|
5
3
|
import { RootComponent } from "../..";
|
|
6
4
|
|
|
7
|
-
type Gender = "male" | "female";
|
|
8
|
-
|
|
9
|
-
const RootDoc = RootComponent()({
|
|
10
|
-
data: {
|
|
11
|
-
gender: "male" as Gender, // 联合字面量
|
|
12
|
-
num: 123,
|
|
13
|
-
_innernalFields: 123, // 内部字段无法在wxml中使用
|
|
14
|
-
},
|
|
15
|
-
methods: {
|
|
16
|
-
foo() {
|
|
17
|
-
this.cloneData.num = 123;
|
|
18
|
-
|
|
19
|
-
Checking<
|
|
20
|
-
typeof this.data,
|
|
21
|
-
ReadonlyDeep<{ gender: Gender; num: number; _innernalFields: number } & IInjectData>,
|
|
22
|
-
Test.Pass
|
|
23
|
-
>;
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
type RootDocExpected = {
|
|
29
|
-
gender: Gender;
|
|
30
|
-
num: number;
|
|
31
|
-
_innernalFields: number;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
Checking<typeof RootDoc["data"], RootDocExpected, Test.Pass>;
|
|
35
|
-
|
|
36
5
|
// data为空对象时
|
|
37
6
|
const EmptyDataRootDoc = RootComponent()({
|
|
38
7
|
data: {},
|
|
39
8
|
methods: {
|
|
40
9
|
M1() {
|
|
41
|
-
// 3.1 data为空对象时 this.data
|
|
42
|
-
Checking<typeof this.data,
|
|
10
|
+
// 3.1 data为空对象时 this.data为注入数据类型
|
|
11
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
43
12
|
},
|
|
44
13
|
},
|
|
45
14
|
});
|
|
@@ -53,8 +22,8 @@ Checking<typeof EmptyDataRootDoc, { methods: { M1: () => void } }, Test.Pass>;
|
|
|
53
22
|
const noDataRootDoc = RootComponent()({
|
|
54
23
|
methods: {
|
|
55
24
|
M1() {
|
|
56
|
-
// 4.1 data为空对象时 this.data
|
|
57
|
-
Checking<typeof this.data,
|
|
25
|
+
// 4.1 data为空对象时 this.data为注入数据类型
|
|
26
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
58
27
|
},
|
|
59
28
|
},
|
|
60
29
|
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
2
1
|
import type { IfExtends } from "hry-types/src/Any/IfExtends";
|
|
3
2
|
import type { ComputeIntersection } from "hry-types/src/Object/ComputeIntersection";
|
|
4
3
|
import type { IReactionDisposer } from "mobx";
|
|
@@ -6,7 +5,7 @@ import type { IReactionDisposer } from "mobx";
|
|
|
6
5
|
import type { Assign } from "../../../types/Assign";
|
|
7
6
|
import type { ComputeObject } from "../../../types/ComputeObj";
|
|
8
7
|
import type { WMComponentInstance, WMInstanceMethods, WMPageInstance } from "../../../types/OfficialTypeAlias";
|
|
9
|
-
import type {
|
|
8
|
+
import type { IInjectAllData, IInjectMethods } from "../../InstanceInject/instanceConfig";
|
|
10
9
|
import type { CustomEventMethods } from "./CustomEventMethods";
|
|
11
10
|
import type { CustomSetData } from "./CustomSetData";
|
|
12
11
|
export type RootComponentInstance<
|
|
@@ -16,7 +15,7 @@ export type RootComponentInstance<
|
|
|
16
15
|
AllData extends object,
|
|
17
16
|
CustomEventsDoc extends object,
|
|
18
17
|
StoreDoc extends object,
|
|
19
|
-
instanceData = ComputeObject<Assign<
|
|
18
|
+
instanceData = ComputeObject<Assign<IInjectAllData, ComputeIntersection<AllData>>>,
|
|
20
19
|
> =
|
|
21
20
|
// 官方实例属性is options dataset等
|
|
22
21
|
& IfExtends<false, TIsPage, WMComponentInstance, WMPageInstance>
|
|
@@ -28,8 +27,8 @@ export type RootComponentInstance<
|
|
|
28
27
|
disposer: { [k in keyof StoreDoc]: IReactionDisposer };
|
|
29
28
|
}>
|
|
30
29
|
& Assign<IInjectMethods, TMethods & CustomEventMethods<CustomEventsDoc>>
|
|
31
|
-
& { data:
|
|
32
|
-
|
|
30
|
+
& { data: instanceData };
|
|
31
|
+
// & { cloneData: ComputeObject<Assign<IInjectData, ComputeIntersection<AllData>>> };
|
|
33
32
|
|
|
34
33
|
export type ComponentInstance = RootComponentInstance<false, {}, {}, {}, {}, {}>;
|
|
35
34
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ComputeIntersection } from "hry-types/src/Object/ComputeIntersection";
|
|
3
3
|
import { type DetailedType, RootComponent } from "../../../../..";
|
|
4
|
-
import type {
|
|
4
|
+
import type { IInjectAllData } from "../../../../InstanceInject/instanceConfig";
|
|
5
5
|
|
|
6
6
|
// 组件时
|
|
7
7
|
RootComponent()({
|
|
@@ -17,7 +17,12 @@ RootComponent()({
|
|
|
17
17
|
// 组件实例对象格外添加null类型
|
|
18
18
|
Checking<
|
|
19
19
|
typeof this.data,
|
|
20
|
-
|
|
20
|
+
ComputeIntersection<
|
|
21
|
+
{
|
|
22
|
+
optionalObj: { name: string } | null;
|
|
23
|
+
obj: object | null;
|
|
24
|
+
} & IInjectAllData
|
|
25
|
+
>,
|
|
21
26
|
Test.Pass
|
|
22
27
|
>;
|
|
23
28
|
},
|
|
@@ -44,7 +49,7 @@ RootComponent()({
|
|
|
44
49
|
}, Test.Pass>;
|
|
45
50
|
|
|
46
51
|
// 页面实例对象不额外添加null
|
|
47
|
-
Checking<typeof this.data.optionalObj,
|
|
52
|
+
Checking<typeof this.data.optionalObj, { name: string }, Test.Pass>;
|
|
48
53
|
|
|
49
54
|
// 页面实例对象不额外添加null
|
|
50
55
|
Checking<typeof this.data.obj, object, Test.Pass>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
2
1
|
import type { IfExtends } from "hry-types/src/Any/IfExtends";
|
|
3
2
|
import type { IsPureObject } from "hry-types/src/Any/IsPureObject";
|
|
4
3
|
import type { NoInfer } from "hry-types/src/Generic/NoInfer";
|
|
@@ -20,15 +19,13 @@ type AddFieldsOfObject<
|
|
|
20
19
|
> = {
|
|
21
20
|
[k in secondKeys]?: (
|
|
22
21
|
// @ts-ignore
|
|
23
|
-
newValue:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
NonNullable<(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]>
|
|
31
|
-
>
|
|
22
|
+
newValue: IfExtends<
|
|
23
|
+
getLastKeys<k>,
|
|
24
|
+
"**",
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
TWatchData[getFirstKeys<k>],
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
NonNullable<(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]>
|
|
32
29
|
>,
|
|
33
30
|
) => void;
|
|
34
31
|
};
|
|
@@ -46,7 +43,7 @@ export type ObserversOption<TWatchData extends object, _WatchKeys extends keyof
|
|
|
46
43
|
NoInfer<
|
|
47
44
|
& {
|
|
48
45
|
[k in _WatchKeys | "**"]?: (
|
|
49
|
-
newValue: k extends keyof TWatchData ?
|
|
46
|
+
newValue: k extends keyof TWatchData ? TWatchData[k] : unknown,
|
|
50
47
|
) => void;
|
|
51
48
|
}
|
|
52
49
|
// 解决单独书写计算书写字段的报错(或许是:ts字面量约束检测提前计算属性key引起的错误提示)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
3
2
|
|
|
4
3
|
import type { User } from "../../../../../jest/common";
|
|
5
4
|
import { RootComponent } from "../..";
|
|
@@ -10,10 +9,10 @@ RootComponent()({
|
|
|
10
9
|
},
|
|
11
10
|
observers: {
|
|
12
11
|
obj(a) {
|
|
13
|
-
Checking<typeof a,
|
|
12
|
+
Checking<typeof a, User | null, Test.Pass>;
|
|
14
13
|
},
|
|
15
14
|
"obj.**"(a) {
|
|
16
|
-
Checking<typeof a,
|
|
15
|
+
Checking<typeof a, User | null, Test.Pass>;
|
|
17
16
|
},
|
|
18
17
|
"obj.age"(a) {
|
|
19
18
|
Checking<typeof a, number, Test.Pass>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
import type {
|
|
3
|
-
import type { IInjectData } from "../../../InstanceInject/instanceConfig";
|
|
2
|
+
import type { IInjectAllData } from "../../../InstanceInject/instanceConfig";
|
|
4
3
|
import { RootComponent } from "../..";
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -10,8 +9,8 @@ const emptyObj = RootComponent()({
|
|
|
10
9
|
properties: {},
|
|
11
10
|
methods: {
|
|
12
11
|
foo() {
|
|
13
|
-
// 1 this.data
|
|
14
|
-
Checking<typeof this.data,
|
|
12
|
+
// 1 this.data 为注入数据类型
|
|
13
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
15
14
|
},
|
|
16
15
|
},
|
|
17
16
|
});
|
|
@@ -29,8 +28,8 @@ Checking<typeof emptyObj, {
|
|
|
29
28
|
const noProperties = RootComponent()({
|
|
30
29
|
methods: {
|
|
31
30
|
foo() {
|
|
32
|
-
// 3 this.data
|
|
33
|
-
Checking<typeof this.data,
|
|
31
|
+
// 3 this.data 为注入数据类型
|
|
32
|
+
Checking<typeof this.data, IInjectAllData, Test.Pass>;
|
|
34
33
|
},
|
|
35
34
|
},
|
|
36
35
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ComputeIntersection } from "hry-types/src/Object/_api";
|
|
3
3
|
import type { DetailedType } from "../../../../types/DetailedType";
|
|
4
|
-
import type {
|
|
4
|
+
import type { IInjectAllData } from "../../../InstanceInject/instanceConfig";
|
|
5
5
|
import { RootComponent } from "../..";
|
|
6
6
|
import { type Mock_User } from "./normalRequired.test";
|
|
7
7
|
|
|
@@ -48,7 +48,7 @@ const OptionalDoc = RootComponent()({
|
|
|
48
48
|
// 1. 内部this.data中的类型(去除可选)
|
|
49
49
|
Checking<
|
|
50
50
|
typeof this.data,
|
|
51
|
-
|
|
51
|
+
ComputeIntersection<
|
|
52
52
|
{
|
|
53
53
|
optional_num: number;
|
|
54
54
|
optional_gender: "male" | "female";
|
|
@@ -57,7 +57,7 @@ const OptionalDoc = RootComponent()({
|
|
|
57
57
|
optional_objOrNull: Mock_User | null;
|
|
58
58
|
optional_union: string | number;
|
|
59
59
|
optional_arr: string[];
|
|
60
|
-
} &
|
|
60
|
+
} & IInjectAllData
|
|
61
61
|
>,
|
|
62
62
|
Test.Pass
|
|
63
63
|
>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Checking, type Test } from "hry-types";
|
|
2
|
+
import type { ComputeIntersection } from "hry-types/src/Object/ComputeIntersection";
|
|
2
3
|
import type { DetailedType } from "../../../../types/DetailedType";
|
|
3
|
-
|
|
4
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
5
|
-
import type { IInjectData } from "../../../InstanceInject/instanceConfig";
|
|
4
|
+
import type { IInjectAllData } from "../../../InstanceInject/instanceConfig";
|
|
6
5
|
import { RootComponent } from "../..";
|
|
7
6
|
import type { RequiredSingle, RequiredType, RequiredUnion } from "../PropertiesConstraint";
|
|
8
7
|
|
|
@@ -92,10 +91,11 @@ const RequiredDoc = RootComponent()({
|
|
|
92
91
|
methods: {
|
|
93
92
|
foo() {
|
|
94
93
|
// 1 this.data中的类型(对象类型加null)
|
|
95
|
-
Checking<typeof this.data,
|
|
94
|
+
Checking<typeof this.data, ComputeIntersection<RequiredTypeExpected & IInjectAllData>, Test.Pass>;
|
|
96
95
|
},
|
|
97
96
|
},
|
|
98
97
|
});
|
|
98
|
+
|
|
99
99
|
/**
|
|
100
100
|
* 2 properties配置为必传类型时预期文档类型(与this.data一致)
|
|
101
101
|
*/
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ReadonlyDeep } from "hry-types/src/Any/_api";
|
|
2
1
|
import type { IfExtends } from "hry-types/src/Any/IfExtends";
|
|
3
2
|
import type { IsPureObject } from "hry-types/src/Any/IsPureObject";
|
|
4
3
|
import type { NoInfer } from "hry-types/src/Generic/NoInfer";
|
|
@@ -20,27 +19,22 @@ type AddFieldsOfObject<
|
|
|
20
19
|
> = {
|
|
21
20
|
[k in secondKeys]?: (
|
|
22
21
|
// @ts-ignore
|
|
23
|
-
newValue:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
NonNullable<(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]>
|
|
31
|
-
>
|
|
22
|
+
newValue: IfExtends<
|
|
23
|
+
getLastKeys<k>,
|
|
24
|
+
"**",
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
Exclude<TWatchData[getFirstKeys<k>], null>,
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
NonNullable<(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]>
|
|
32
29
|
>,
|
|
33
|
-
oldValue:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]
|
|
41
|
-
>
|
|
30
|
+
oldValue: IfExtends<
|
|
31
|
+
getLastKeys<k>,
|
|
32
|
+
"**",
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
TWatchData[getFirstKeys<k>],
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]
|
|
42
37
|
>,
|
|
43
|
-
// ReadonlyDeep<(Exclude<TWatchData[getFirstKeys<k>], null>)[getLastKeys<k>]>,
|
|
44
38
|
) => void;
|
|
45
39
|
};
|
|
46
40
|
|
|
@@ -57,9 +51,9 @@ export type WatchOption<TWatchData extends object, _WatchKeys extends keyof TWat
|
|
|
57
51
|
NoInfer<
|
|
58
52
|
& {
|
|
59
53
|
[k in _WatchKeys]?: (
|
|
60
|
-
// newValue 去除null
|
|
61
|
-
newValue:
|
|
62
|
-
oldValue:
|
|
54
|
+
// newValue 去除null
|
|
55
|
+
newValue: Exclude<TWatchData[k], null>,
|
|
56
|
+
oldValue: TWatchData[k],
|
|
63
57
|
) => void;
|
|
64
58
|
}
|
|
65
59
|
// 解决单独书写计算书写字段的报错(猜测是:ts字面量约束检测提前计算属性key引起的错误提示)
|