deveco-harness 0.1.0

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.
Files changed (135) hide show
  1. package/README.en.md +71 -0
  2. package/README.md +71 -0
  3. package/deveco-harness.example.jsonc +32 -0
  4. package/dist/index.js +758 -0
  5. package/package.json +48 -0
  6. package/prompts/build.txt +164 -0
  7. package/prompts/plan.txt +118 -0
  8. package/skills/arkts-error-fixes/README.md +151 -0
  9. package/skills/arkts-error-fixes/SKILL.md +150 -0
  10. package/skills/arkts-error-fixes/assets/AnyTypeError.ets +269 -0
  11. package/skills/arkts-error-fixes/assets/AppStorageError.ets +22 -0
  12. package/skills/arkts-error-fixes/assets/ArrowFunctionConversionError.ets +42 -0
  13. package/skills/arkts-error-fixes/assets/AvoidAreaTypeError.ets +43 -0
  14. package/skills/arkts-error-fixes/assets/BreakpointTypeError.ets +71 -0
  15. package/skills/arkts-error-fixes/assets/CatchClauseTypeError.ets +54 -0
  16. package/skills/arkts-error-fixes/assets/ColorConsistencyError.ets +88 -0
  17. package/skills/arkts-error-fixes/assets/ColorPropertyError.ets +39 -0
  18. package/skills/arkts-error-fixes/assets/ContextTypeError.ets +105 -0
  19. package/skills/arkts-error-fixes/assets/DecoratorStateError.ets +64 -0
  20. package/skills/arkts-error-fixes/assets/DisplayListenerTypeError.ets +129 -0
  21. package/skills/arkts-error-fixes/assets/DuplicateEntryError.ets +35 -0
  22. package/skills/arkts-error-fixes/assets/ESObjectTypeError.ets +137 -0
  23. package/skills/arkts-error-fixes/assets/FontColorPropertyError.ets +42 -0
  24. package/skills/arkts-error-fixes/assets/FunctionReturnTypeError.ets +41 -0
  25. package/skills/arkts-error-fixes/assets/IDataSourceError.ets +79 -0
  26. package/skills/arkts-error-fixes/assets/ImplementationNotAllowedError.ets +38 -0
  27. package/skills/arkts-error-fixes/assets/InterfaceMethodSignatureError.ets +43 -0
  28. package/skills/arkts-error-fixes/assets/NotificationError.ets +34 -0
  29. package/skills/arkts-error-fixes/assets/ObjectLiteralInterfaceError.ets +49 -0
  30. package/skills/arkts-error-fixes/assets/ObjectLiteralTypeError.ets +54 -0
  31. package/skills/arkts-error-fixes/assets/ObjectSpreadError.ets +29 -0
  32. package/skills/arkts-error-fixes/assets/PossiblyNullError.ets +32 -0
  33. package/skills/arkts-error-fixes/assets/ResourceConversionError.ets +159 -0
  34. package/skills/arkts-error-fixes/assets/StandaloneFunctionContext.ets +116 -0
  35. package/skills/arkts-error-fixes/assets/StandaloneFunctionError.ets +85 -0
  36. package/skills/arkts-error-fixes/assets/StorageLinkDefaultError.ets +41 -0
  37. package/skills/arkts-error-fixes/assets/TitleButtonRectTypeError.ets +86 -0
  38. package/skills/arkts-error-fixes/assets/UnusedVariableWarning.ets +102 -0
  39. package/skills/arkts-error-fixes/assets/UtilityTypeError.ets +176 -0
  40. package/skills/arkts-error-fixes/assets/WindowRectSizeError.ets +65 -0
  41. package/skills/arkts-error-fixes/assets/WindowTypeError.ets +37 -0
  42. package/skills/arkts-error-fixes/reference/any_type_errors.md +433 -0
  43. package/skills/arkts-error-fixes/reference/appstorage_errors.md +95 -0
  44. package/skills/arkts-error-fixes/reference/arrow_function_conversion_errors.md +163 -0
  45. package/skills/arkts-error-fixes/reference/avoid_area_type_errors.md +59 -0
  46. package/skills/arkts-error-fixes/reference/breakpoint_type_errors.md +122 -0
  47. package/skills/arkts-error-fixes/reference/catch_clause_type_errors.md +89 -0
  48. package/skills/arkts-error-fixes/reference/color_consistency_errors.md +209 -0
  49. package/skills/arkts-error-fixes/reference/color_property_errors.md +136 -0
  50. package/skills/arkts-error-fixes/reference/context_type_errors.md +260 -0
  51. package/skills/arkts-error-fixes/reference/decorator_state_errors.md +109 -0
  52. package/skills/arkts-error-fixes/reference/display_listener_type_errors.md +149 -0
  53. package/skills/arkts-error-fixes/reference/duplicate_entry_errors.md +193 -0
  54. package/skills/arkts-error-fixes/reference/esobject_type_errors.md +110 -0
  55. package/skills/arkts-error-fixes/reference/fontcolor_property_errors.md +104 -0
  56. package/skills/arkts-error-fixes/reference/function_return_type_errors.md +194 -0
  57. package/skills/arkts-error-fixes/reference/idata_source_errors.md +77 -0
  58. package/skills/arkts-error-fixes/reference/implementation_not_allowed_errors.md +191 -0
  59. package/skills/arkts-error-fixes/reference/interface_method_signature_errors.md +143 -0
  60. package/skills/arkts-error-fixes/reference/notification_errors.md +110 -0
  61. package/skills/arkts-error-fixes/reference/object_literal_interface_errors.md +156 -0
  62. package/skills/arkts-error-fixes/reference/object_literal_type_errors.md +110 -0
  63. package/skills/arkts-error-fixes/reference/object_spread_errors.md +105 -0
  64. package/skills/arkts-error-fixes/reference/possibly_null_errors.md +156 -0
  65. package/skills/arkts-error-fixes/reference/resource_conversion_errors.md +154 -0
  66. package/skills/arkts-error-fixes/reference/standalone_function_errors.md +68 -0
  67. package/skills/arkts-error-fixes/reference/storage_link_default_errors.md +124 -0
  68. package/skills/arkts-error-fixes/reference/title_button_rect_type_errors.md +167 -0
  69. package/skills/arkts-error-fixes/reference/unused_variable_warnings.md +295 -0
  70. package/skills/arkts-error-fixes/reference/utility_type_errors.md +290 -0
  71. package/skills/arkts-error-fixes/reference/window_rect_size_errors.md +70 -0
  72. package/skills/arkts-error-fixes/reference/window_type_errors.md +95 -0
  73. package/skills/arkts-grammar-standards/SKILL.md +71 -0
  74. package/skills/arkts-grammar-standards/references/basic-syntax.md +103 -0
  75. package/skills/arkts-grammar-standards/references/restrictions.md +100 -0
  76. package/skills/arkts-grammar-standards/references/topic-aliases.json +93 -0
  77. package/skills/arkts-grammar-standards/references/ts-diff.md +108 -0
  78. package/skills/arkts-runtime-fix/SKILL.md +152 -0
  79. package/skills/arkts-runtime-fix/SKILL_CN.md +123 -0
  80. package/skills/arkts-runtime-fix/evals/evals.json +17 -0
  81. package/skills/arkts-runtime-fix/scripts/collect-hilog.mjs +116 -0
  82. package/skills/arkts-runtime-fix/scripts/collect-hilog.ts +115 -0
  83. package/skills/arkts-runtime-fix/scripts/fetch-faultlog.mjs +117 -0
  84. package/skills/arkts-runtime-fix/scripts/fetch-faultlog.ts +116 -0
  85. package/skills/arkts-runtime-fix/scripts/jscrash-report.mjs +149 -0
  86. package/skills/arkts-runtime-fix/scripts/parse-jscrash-log.mjs +126 -0
  87. package/skills/arkts-runtime-fix/scripts/parse-jscrash-log.ts +126 -0
  88. package/skills/arkts-runtime-fix/scripts/probe-faultlogger.mjs +160 -0
  89. package/skills/arkts-runtime-fix/scripts/probe-faultlogger.ts +160 -0
  90. package/skills/arkts-runtime-fix/scripts/shared/hdc.mjs +107 -0
  91. package/skills/arkts-runtime-fix/scripts/shared/hdc.ts +58 -0
  92. package/skills/arkts-runtime-fix/scripts/shared/jscrash-faultlogger.mjs +143 -0
  93. package/skills/arkts-runtime-fix/scripts/shared/jscrash-faultlogger.ts +148 -0
  94. package/skills/arkts-runtime-fix/scripts/shared/jscrash-parse.mjs +389 -0
  95. package/skills/arkts-runtime-fix/scripts/shared/jscrash-parse.ts +409 -0
  96. package/skills/arkts-runtime-fix/scripts/shared/utils.mjs +27 -0
  97. package/skills/arkts-runtime-fix/scripts/shared/utils.ts +27 -0
  98. package/skills/arkui-knowledge/SKILL.md +90 -0
  99. package/skills/arkui-knowledge/references/api-guardrails.md +60 -0
  100. package/skills/arkui-knowledge/references/common-mistakes.md +119 -0
  101. package/skills/arkui-knowledge/references/component-cookbook.md +135 -0
  102. package/skills/arkui-knowledge/references/ui-quality-checklist.md +36 -0
  103. package/skills/deveco-create-project/SKILL.md +144 -0
  104. package/skills/deveco-create-project/application/AppScope/app.json5 +10 -0
  105. package/skills/deveco-create-project/application/AppScope/resources/base/element/string.json +8 -0
  106. package/skills/deveco-create-project/application/AppScope/resources/base/media/background.png +0 -0
  107. package/skills/deveco-create-project/application/AppScope/resources/base/media/foreground.png +0 -0
  108. package/skills/deveco-create-project/application/AppScope/resources/base/media/layered_image.json +7 -0
  109. package/skills/deveco-create-project/application/build-profile.json5 +42 -0
  110. package/skills/deveco-create-project/application/code-linter.json5 +32 -0
  111. package/skills/deveco-create-project/application/entry/build-profile.json5 +33 -0
  112. package/skills/deveco-create-project/application/entry/hvigorfile.ts +7 -0
  113. package/skills/deveco-create-project/application/entry/obfuscation-rules.txt +23 -0
  114. package/skills/deveco-create-project/application/entry/oh-package.json5 +10 -0
  115. package/skills/deveco-create-project/application/entry/src/main/ets/entryability/EntryAbility.ets +63 -0
  116. package/skills/deveco-create-project/application/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +31 -0
  117. package/skills/deveco-create-project/application/entry/src/main/ets/pages/Index.ets +38 -0
  118. package/skills/deveco-create-project/application/entry/src/main/module.json5 +50 -0
  119. package/skills/deveco-create-project/application/entry/src/main/resources/base/element/color.json +8 -0
  120. package/skills/deveco-create-project/application/entry/src/main/resources/base/element/float.json +8 -0
  121. package/skills/deveco-create-project/application/entry/src/main/resources/base/element/string.json +16 -0
  122. package/skills/deveco-create-project/application/entry/src/main/resources/base/media/background.png +0 -0
  123. package/skills/deveco-create-project/application/entry/src/main/resources/base/media/foreground.png +0 -0
  124. package/skills/deveco-create-project/application/entry/src/main/resources/base/media/layered_image.json +7 -0
  125. package/skills/deveco-create-project/application/entry/src/main/resources/base/media/startIcon.png +0 -0
  126. package/skills/deveco-create-project/application/entry/src/main/resources/base/profile/backup_config.json +3 -0
  127. package/skills/deveco-create-project/application/entry/src/main/resources/base/profile/main_pages.json +5 -0
  128. package/skills/deveco-create-project/application/entry/src/main/resources/dark/element/color.json +8 -0
  129. package/skills/deveco-create-project/application/hvigor/hvigor-config.json5 +23 -0
  130. package/skills/deveco-create-project/application/hvigorfile.ts +7 -0
  131. package/skills/deveco-create-project/application/oh-package.json5 +10 -0
  132. package/skills/deveco-create-project/scripts/copy-template.mjs +216 -0
  133. package/skills/deveco-create-project/scripts/copy-template.ts +214 -0
  134. package/skills/deveco-create-project/scripts/detect-sdk.mjs +82 -0
  135. package/skills/deveco-create-project/scripts/detect-sdk.ts +95 -0
@@ -0,0 +1,260 @@
1
+ # Context 类型错误解决方案
2
+
3
+ ## 问题描述
4
+
5
+ 在 HarmonyOS ArkUI 开发中,使用 `this.getUIContext().getHostContext()` 获取的 Context 类型为 `Context | undefined`,直接传递给需要 `Context` 类型参数的函数会触发类型错误:
6
+
7
+ ```
8
+ Argument of type 'Context | undefined' is not assignable to parameter of type 'Context'.
9
+ ```
10
+
11
+ ## 问题示例
12
+
13
+ ```typescript
14
+ // ❌ 错误:Context 可能为 undefined
15
+ const context = this.getUIContext().getHostContext();
16
+ await window.getLastWindow(context); // 类型错误
17
+ ```
18
+
19
+ ## 推荐解决方案
20
+
21
+ ### 方案 1: 添加 null 检查
22
+
23
+ ```typescript
24
+ // ✅ 推荐:添加 null 检查
25
+ const context = this.getUIContext().getHostContext();
26
+ if (context) {
27
+ await window.getLastWindow(context);
28
+ }
29
+ ```
30
+
31
+ ### 方案 2: 使用类型断言
32
+
33
+ ```typescript
34
+ // ✅ 可选:使用类型断言
35
+ const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
36
+ await window.getLastWindow(context);
37
+ ```
38
+
39
+ ### 方案 3: 使用可选链和空值合并
40
+
41
+ ```typescript
42
+ // ✅ 可选:使用可选链
43
+ const context = this.getUIContext().getHostContext();
44
+ if (context) {
45
+ await window.getLastWindow(context);
46
+ }
47
+ ```
48
+
49
+ ## 迁移步骤
50
+
51
+ ### 1. 识别 Context 类型错误
52
+
53
+ ```typescript
54
+ // 查找代码中的 Context 使用
55
+ const context = this.getUIContext().getHostContext();
56
+ window.getLastWindow(context); // 类型错误
57
+ ```
58
+
59
+ ### 2. 添加 null 检查
60
+
61
+ ```typescript
62
+ const context = this.getUIContext().getHostContext();
63
+ if (context) {
64
+ window.getLastWindow(context); // 正确
65
+ }
66
+ ```
67
+
68
+ ### 3. 使用类型断言(可选)
69
+
70
+ ```typescript
71
+ const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
72
+ window.getLastWindow(context); // 正确
73
+ ```
74
+
75
+ ## 完整示例
76
+
77
+ ```typescript
78
+ import { window } from '@kit.ArkUI';
79
+ import { common } from '@kit.AbilityKit';
80
+
81
+ @Entry
82
+ @Component
83
+ struct ContextTypeExample {
84
+ @State windowWidth: number = 0;
85
+ @State windowHeight: number = 0;
86
+
87
+ async aboutToAppear() {
88
+ // ✅ 正确:添加 null 检查
89
+ const context = this.getUIContext().getHostContext();
90
+ if (context) {
91
+ await this.getWindowSize(context as common.UIAbilityContext);
92
+ }
93
+ }
94
+
95
+ private async getWindowSize(context: common.UIAbilityContext) {
96
+ try {
97
+ const win = await window.getLastWindow(context);
98
+ const properties = win.getWindowProperties();
99
+ this.windowWidth = properties.windowRect.width;
100
+ this.windowHeight = properties.windowRect.height;
101
+ } catch (err) {
102
+ console.error('获取窗口大小失败:', err);
103
+ }
104
+ }
105
+
106
+ build() {
107
+ Column() {
108
+ Text(`窗口大小: ${this.windowWidth} x ${this.windowHeight}`)
109
+ .fontSize(16)
110
+ }
111
+ .width('100%')
112
+ .height('100%')
113
+ .padding(16)
114
+ }
115
+ }
116
+ ```
117
+
118
+ > [查看完整示例](../assets/ContextTypeError.ets)
119
+
120
+ ## 使用场景
121
+
122
+ ### 1. 窗口操作
123
+
124
+ ```typescript
125
+ async operateWindow() {
126
+ const context = this.getUIContext().getHostContext();
127
+ if (context) {
128
+ const win = await window.getLastWindow(context);
129
+ await win.resize(800, 600);
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### 2. 媒体查询
135
+
136
+ ```typescript
137
+ setupMediaQuery() {
138
+ const context = this.getUIContext().getHostContext();
139
+ if (context) {
140
+ const mediaQuery = this.getUIContext().getMediaQuery();
141
+ const listener = mediaQuery.matchMediaSync('(min-width: 600vp)');
142
+ listener.on('change', (result) => {
143
+ console.info(`Matches: ${result.matches}`);
144
+ });
145
+ }
146
+ }
147
+ ```
148
+
149
+ ### 3. 文件操作
150
+
151
+ ```typescript
152
+ async readFile() {
153
+ const context = this.getUIContext().getHostContext();
154
+ if (context) {
155
+ const filesDir = context.filesDir;
156
+ // 读取文件操作
157
+ }
158
+ }
159
+ ```
160
+
161
+ ## 最佳实践
162
+
163
+ ### 1. 始终添加 null 检查
164
+
165
+ ```typescript
166
+ const context = this.getUIContext().getHostContext();
167
+ if (!context) {
168
+ console.error('Context is undefined');
169
+ return;
170
+ }
171
+ // 使用 context
172
+ ```
173
+
174
+ ### 2. 使用类型断言明确类型
175
+
176
+ ```typescript
177
+ const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
178
+ ```
179
+
180
+ ### 3. 封装 Context 获取
181
+
182
+ ```typescript
183
+ private getSafeContext(): common.UIAbilityContext | null {
184
+ const context = this.getUIContext().getHostContext();
185
+ return context ? context as common.UIAbilityContext : null;
186
+ }
187
+
188
+ async operateWindow() {
189
+ const context = this.getSafeContext();
190
+ if (context) {
191
+ const win = await window.getLastWindow(context);
192
+ // 操作窗口
193
+ }
194
+ }
195
+ ```
196
+
197
+ ### 4. 处理异步操作
198
+
199
+ ```typescript
200
+ async asyncOperation() {
201
+ const context = this.getUIContext().getHostContext();
202
+ if (context) {
203
+ try {
204
+ const win = await window.getLastWindow(context);
205
+ // 异步操作
206
+ } catch (err) {
207
+ console.error('操作失败:', err);
208
+ }
209
+ }
210
+ }
211
+ ```
212
+
213
+ ## 注意事项
214
+
215
+ 1. **类型定义**:`getHostContext()` 返回 `Context | undefined`,必须处理 undefined 情况
216
+
217
+ 2. **null 检查**:建议使用 `if (context)` 检查,而不是直接使用
218
+
219
+ 3. **类型断言**:使用 `as common.UIAbilityContext` 明确类型,但确保类型正确
220
+
221
+ 4. **异常处理**:在异步操作中添加 try-catch 处理可能的异常
222
+
223
+ 5. **封装复用**:可以将 Context 获取逻辑封装为工具函数
224
+
225
+ ## 相关 API 参考
226
+
227
+ - [UIContext.getHostContext()](https://developer.harmonyos.com/cn/docs/documentation/reference/arkui-ts/ts-methods-uicontext)
228
+ - [Context](https://developer.harmonyos.com/cn/docs/documentation/reference/apis-js-apis-application-context)
229
+ - [window.getLastWindow()](https://developer.harmonyos.com/cn/docs/documentation/reference/apis-arkui-window-0000001774529169)
230
+
231
+ ## 迁移检查清单
232
+
233
+ - [ ] 识别所有使用 `getHostContext()` 的地方
234
+ - [ ] 添加 null 检查处理 undefined 情况
235
+ - [ ] 使用类型断言明确 Context 类型
236
+ - [ ] 添加异常处理
237
+ - [ ] 测试功能是否正常
238
+ - [ ] 确认类型错误已解决
239
+
240
+ ## 常见问题
241
+
242
+ ### Q: 为什么 `getHostContext()` 可能返回 undefined?
243
+
244
+ A: 在某些情况下(如组件未完全初始化),Context 可能尚未准备好,因此返回 undefined。
245
+
246
+ ### Q: 可以使用非空断言 `!` 吗?
247
+
248
+ A: 可以,但不推荐。使用 `!` 会跳过类型检查,可能导致运行时错误。建议使用 null 检查。
249
+
250
+ ### Q: 什么时候应该使用类型断言?
251
+
252
+ A: 当你确定 Context 的具体类型(如 `UIAbilityContext`)时,可以使用类型断言提高代码可读性。
253
+
254
+ ### Q: 如何在多个地方复用 Context?
255
+
256
+ A: 可以封装一个工具函数或在组件中定义一个私有方法来安全地获取 Context。
257
+
258
+ ### Q: null 检查会影响性能吗?
259
+
260
+ A: 不会。null 检查是非常轻量级的操作,对性能影响可以忽略不计。
@@ -0,0 +1,109 @@
1
+ # @State 装饰器错误
2
+
3
+ ## 错误描述
4
+
5
+ 在 ArkTS 中,`@State` 装饰器只能用于 `@Component` 修饰的 struct 中,不能用于普通 class。
6
+
7
+ ## 错误示例
8
+
9
+ ```typescript
10
+ // ❌ AI 经常生成的错误代码
11
+ class FoldableStateManager {
12
+ @State currentBreakpoint: string = 'sm';
13
+ @State isFolded: boolean = true;
14
+
15
+ aboutToAppear() {
16
+ // ...
17
+ }
18
+ }
19
+ ```
20
+
21
+ **错误信息:**
22
+ ```
23
+ The '@State' decorator can only be used with 'struct'.
24
+ ```
25
+
26
+ ## 原因分析
27
+
28
+ `@State` 是 ArkUI 框架的状态管理装饰器,用于在组件内部管理状态。它只能与 `@Component` 一起使用,不能用于普通类。
29
+
30
+ ## 解决方案
31
+
32
+ ### 方案1:移除 @State 装饰器(推荐用于非组件类)
33
+
34
+ 如果类不需要响应式状态管理,移除 `@State` 装饰器:
35
+
36
+ ```typescript
37
+ // ✅ 正确的代码
38
+ class FoldableStateManager {
39
+ currentBreakpoint: string = 'sm';
40
+ isFolded: boolean = true;
41
+
42
+ aboutToAppear() {
43
+ // ...
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### 方案2:使用 @Component struct(推荐用于状态管理)
49
+
50
+ 如果需要状态管理,将类改为 @Component struct:
51
+
52
+ ```typescript
53
+ // ✅ 正确的代码
54
+ @Component
55
+ struct FoldableStateManager {
56
+ @State currentBreakpoint: string = 'sm';
57
+ @State isFolded: boolean = true;
58
+
59
+ aboutToAppear() {
60
+ // ...
61
+ }
62
+
63
+ build() {
64
+ // UI 组件
65
+ }
66
+ }
67
+ ```
68
+
69
+ ## 简单示例
70
+
71
+ ### 用于工具类
72
+
73
+ ```typescript
74
+ // ✅ 用于工具类时移除 @State
75
+ class DisplayManager {
76
+ currentBreakpoint: string = 'sm';
77
+
78
+ updateBreakpoint(width: number): string {
79
+ if (width < 600) return 'sm';
80
+ if (width < 840) return 'md';
81
+ return 'lg';
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### 用于 @Component struct
87
+
88
+ ```typescript
89
+ // ✅ 用于组件时保留 @State
90
+ @Component
91
+ struct AdaptiveLayout {
92
+ @State currentBreakpoint: string = 'sm';
93
+
94
+ build() {
95
+ Column() {
96
+ Text(`Current: ${this.currentBreakpoint}`)
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## 详细代码示例
103
+
104
+ > [DecoratorStateError.ets](../assets/DecoratorStateError.ets) - 完整的 @State 装饰器错误示例和修复方案
105
+
106
+ ## 相关文档
107
+
108
+ - [ArkTS 状态管理](./state_migration.md)
109
+ - [HarmonyOS 官方文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-overview)
@@ -0,0 +1,149 @@
1
+ # Display Listener Type Errors
2
+
3
+ ## Error: Display on/off method type error
4
+
5
+ ### Error Message
6
+ ```
7
+ Type 'void' is not assignable to type 'number'
8
+ Argument of type 'number' is not assignable to parameter of type 'Callback<Rect>'
9
+ ```
10
+
11
+ ### Cause
12
+ The `display.on()` and `display.off()` methods are module-level methods, not instance methods of the `Display` class. Attempting to call them on a `Display` object instance causes type errors.
13
+
14
+ ### Solution
15
+ Use `display.on()` and `display.off()` at the module level for listening to display changes. Use `Display.on()` and `Display.off()` on Display instances for instance-specific events like `availableAreaChange`.
16
+
17
+ ### Key Points
18
+ - `display.on('add'|'remove'|'change', callback)` - Module level methods
19
+ - `Display.on('availableAreaChange', callback)` - Instance level methods
20
+ - `Display.on('foldStatusChange', callback)` - Instance level methods
21
+ - `Display.on('captureStatusChange', callback)` - Instance level methods
22
+
23
+ ### Module Level Listeners
24
+ ```typescript
25
+ import { display } from '@kit.ArkUI';
26
+
27
+ // ✅ Correct: Module level listener
28
+ let listener: (data: number) => void = (data: number) => {
29
+ console.info(`Display changed, ID: ${data}`);
30
+ };
31
+
32
+ display.on('change', listener);
33
+
34
+ // Unregister
35
+ display.off('change', listener);
36
+ ```
37
+
38
+ ### Instance Level Listeners
39
+ ```typescript
40
+ import { display } from '@kit.ArkUI';
41
+
42
+ const displayClass = display.getDefaultDisplaySync();
43
+
44
+ // ✅ Correct: Instance level listener
45
+ let areaListener: (data: display.Rect) => void = (data: display.Rect) => {
46
+ console.info(`Available area changed: ${JSON.stringify(data)}`);
47
+ };
48
+
49
+ displayClass.on('availableAreaChange', areaListener);
50
+
51
+ // Unregister
52
+ displayClass.off('availableAreaChange', areaListener);
53
+ ```
54
+
55
+ ### ❌ Wrong Usage
56
+ ```typescript
57
+ const displayClass = display.getDefaultDisplaySync();
58
+
59
+ // ❌ Wrong: Calling on() on Display instance
60
+ let listener = displayClass.on('change', () => {
61
+ console.info('Display changed');
62
+ });
63
+
64
+ // ❌ Wrong: Calling off() on Display instance
65
+ displayClass.off('change', listener);
66
+ ```
67
+
68
+ ### ✅ Correct Usage
69
+ ```typescript
70
+ // ✅ Correct: Module level for display changes
71
+ let changeListener: (data: number) => void = (data: number) => {
72
+ console.info(`Display changed, ID: ${data}`);
73
+ };
74
+ display.on('change', changeListener);
75
+
76
+ // ✅ Correct: Instance level for available area changes
77
+ const displayClass = display.getDefaultDisplaySync();
78
+ let areaListener: (data: display.Rect) => void = (data: display.Rect) => {
79
+ console.info(`Available area changed: ${JSON.stringify(data)}`);
80
+ };
81
+ displayClass.on('availableAreaChange', areaListener);
82
+ ```
83
+
84
+ ### Available Listener Types
85
+
86
+ #### Module Level (display module)
87
+ - `on('add', callback: Callback<number>)` - Display added
88
+ - `on('remove', callback: Callback<number>)` - Display removed
89
+ - `on('change', callback: Callback<number>)` - Display changed
90
+
91
+ #### Instance Level (Display object)
92
+ - `on('availableAreaChange', callback: Callback<Rect>)` - Available area changed
93
+ - `on('foldStatusChange', callback: Callback<FoldStatus>)` - Fold status changed
94
+ - `on('captureStatusChange', callback: Callback<boolean>)` - Capture status changed
95
+
96
+ ### Best Practices
97
+ 1. **Use module level** for display add/remove/change events
98
+ 2. **Use instance level** for display-specific events
99
+ 3. **Always unregister** listeners in aboutToDisappear()
100
+ 4. **Store listener references** for proper cleanup
101
+ 5. **Use explicit types** for listener callbacks
102
+
103
+ ### Component Integration
104
+ ```typescript
105
+ @Entry
106
+ @Component
107
+ struct DisplayListenerExample {
108
+ private changeListener?: (data: number) => void;
109
+ private areaListener?: (data: display.Rect) => void;
110
+
111
+ aboutToAppear() {
112
+ // Register module level listener
113
+ this.changeListener = (data: number) => {
114
+ console.info(`Display changed: ${data}`);
115
+ };
116
+ display.on('change', this.changeListener);
117
+
118
+ // Register instance level listener
119
+ const displayClass = display.getDefaultDisplaySync();
120
+ this.areaListener = (data: display.Rect) => {
121
+ console.info(`Area changed: ${JSON.stringify(data)}`);
122
+ };
123
+ displayClass.on('availableAreaChange', this.areaListener);
124
+ }
125
+
126
+ aboutToDisappear() {
127
+ // Unregister listeners
128
+ if (this.changeListener) {
129
+ display.off('change', this.changeListener);
130
+ this.changeListener = undefined;
131
+ }
132
+ if (this.areaListener) {
133
+ const displayClass = display.getDefaultDisplaySync();
134
+ displayClass.off('availableAreaChange', this.areaListener);
135
+ this.areaListener = undefined;
136
+ }
137
+ }
138
+
139
+ build() {
140
+ Column() {
141
+ Text('Display Listener Example')
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ### Related Files
148
+ - [Code Example](../assets/DisplayListenerTypeError.ets)
149
+ - [Display API Documentation](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-display)
@@ -0,0 +1,193 @@
1
+ # 多个 @Entry 装饰器错误
2
+
3
+ ## 问题描述
4
+
5
+ 在 ArkTS 中,一个 `.ets` 文件只能有一个 `@Entry` 装饰器。如果在同一个文件中使用多个 `@Entry` 装饰器,会导致编译错误。
6
+
7
+ ### 错误信息
8
+
9
+ ```
10
+ Duplicate entry annotation
11
+ ```
12
+
13
+
14
+
15
+ ```
16
+ More than one @Entry decorator in the same file
17
+ ```
18
+
19
+ ## 错误示例
20
+
21
+ ```typescript
22
+ // ❌ 错误:一个文件中有两个 @Entry
23
+ @Entry
24
+ @Component
25
+ struct FirstPage {
26
+ build() {
27
+ Column() {
28
+ Text('Page 1')
29
+ }
30
+ }
31
+ }
32
+
33
+ @Entry
34
+ @Component
35
+ struct SecondPage {
36
+ build() {
37
+ Column() {
38
+ Text('Page 2')
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ ## 解决方案
45
+
46
+ ### 方案一:将子组件改为普通 @Component(推荐)
47
+
48
+ 将多余的 `@Entry` 改为普通 `@Component`,避免重复的入口声明。
49
+
50
+ ```typescript
51
+ // ✅ 正确:只有一个 @Entry,其他用 @Component
52
+ @Entry
53
+ @Component
54
+ struct MainPage {
55
+ build() {
56
+ Column() {
57
+ Text('Main Page')
58
+ ChildComponent()
59
+ }
60
+ }
61
+ }
62
+
63
+ @Component
64
+ struct ChildComponent {
65
+ build() {
66
+ Text('Child Component')
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### 方案二:拆分到不同文件
72
+
73
+ 将每个页面组件拆分到独立的文件中。
74
+
75
+ ```typescript
76
+ // mainPage.ets
77
+ @Entry
78
+ @Component
79
+ struct MainPage {
80
+ build() {
81
+ Column() {
82
+ Text('Main Page')
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
88
+ ```typescript
89
+ // subPage.ets - 单独的文件
90
+ @Entry
91
+ @Component
92
+ struct SubPage {
93
+ build() {
94
+ Column() {
95
+ Text('Sub Page')
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### 方案三:使用状态管理实现多页面
102
+
103
+ 如果需要在多个视图之间切换,可以使用 `@State` 和条件渲染:
104
+
105
+ ```typescript
106
+ @Entry
107
+ @Component
108
+ struct MultiViewPage {
109
+ @State currentView: number = 0;
110
+
111
+ build() {
112
+ Column() {
113
+ if (this.currentView === 0) {
114
+ ViewOne()
115
+ } else {
116
+ ViewTwo()
117
+ }
118
+
119
+ Row() {
120
+ Button('View 1')
121
+ .onClick(() => this.currentView = 0)
122
+ Button('View 2')
123
+ .onClick(() => this.currentView = 1)
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ @Component
130
+ struct ViewOne {
131
+ build() {
132
+ Text('View 1').fontSize(24)
133
+ }
134
+ }
135
+
136
+ @Component
137
+ struct ViewTwo {
138
+ build() {
139
+ Text('View 2').fontSize(24)
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## 简单示例
145
+
146
+ ```typescript
147
+ @Entry
148
+ @Component
149
+ struct PageExample {
150
+ @State message: string = 'Hello';
151
+
152
+ build() {
153
+ Column() {
154
+ Text(this.message)
155
+ .fontSize(24)
156
+
157
+ // 使用 @Component 装饰的子组件
158
+ ContentSection()
159
+ }
160
+ .width('100%')
161
+ .height('100%')
162
+ .padding(20)
163
+ }
164
+ }
165
+
166
+ @Component
167
+ struct ContentSection {
168
+ @State count: number = 0;
169
+
170
+ build() {
171
+ Column() {
172
+ Text(`Count: ${this.count}`)
173
+ .fontSize(18)
174
+
175
+ Button('Add')
176
+ .onClick(() => {
177
+ this.count++;
178
+ })
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ ## 详细代码示例
185
+
186
+ - [DuplicateEntryError.ets](../assets/DuplicateEntryError.ets) - 完整的多个 @Entry 错误修复示例
187
+
188
+ ## 最佳实践
189
+
190
+ 1. **每个文件一个 @Entry**:保持每个 `.ets` 文件只有一个入口组件
191
+ 2. **使用 @Component 复用 UI**:使用 `@Component` 装饰器创建可复用的 UI 组件
192
+ 3. **合理拆分文件**:将不同页面拆分到独立文件,便于管理和维护
193
+ 4. **状态提升**:如果多个组件需要共享状态,将状态提升到共同的父组件中