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.
- package/README.en.md +71 -0
- package/README.md +71 -0
- package/deveco-harness.example.jsonc +32 -0
- package/dist/index.js +758 -0
- package/package.json +48 -0
- package/prompts/build.txt +164 -0
- package/prompts/plan.txt +118 -0
- package/skills/arkts-error-fixes/README.md +151 -0
- package/skills/arkts-error-fixes/SKILL.md +150 -0
- package/skills/arkts-error-fixes/assets/AnyTypeError.ets +269 -0
- package/skills/arkts-error-fixes/assets/AppStorageError.ets +22 -0
- package/skills/arkts-error-fixes/assets/ArrowFunctionConversionError.ets +42 -0
- package/skills/arkts-error-fixes/assets/AvoidAreaTypeError.ets +43 -0
- package/skills/arkts-error-fixes/assets/BreakpointTypeError.ets +71 -0
- package/skills/arkts-error-fixes/assets/CatchClauseTypeError.ets +54 -0
- package/skills/arkts-error-fixes/assets/ColorConsistencyError.ets +88 -0
- package/skills/arkts-error-fixes/assets/ColorPropertyError.ets +39 -0
- package/skills/arkts-error-fixes/assets/ContextTypeError.ets +105 -0
- package/skills/arkts-error-fixes/assets/DecoratorStateError.ets +64 -0
- package/skills/arkts-error-fixes/assets/DisplayListenerTypeError.ets +129 -0
- package/skills/arkts-error-fixes/assets/DuplicateEntryError.ets +35 -0
- package/skills/arkts-error-fixes/assets/ESObjectTypeError.ets +137 -0
- package/skills/arkts-error-fixes/assets/FontColorPropertyError.ets +42 -0
- package/skills/arkts-error-fixes/assets/FunctionReturnTypeError.ets +41 -0
- package/skills/arkts-error-fixes/assets/IDataSourceError.ets +79 -0
- package/skills/arkts-error-fixes/assets/ImplementationNotAllowedError.ets +38 -0
- package/skills/arkts-error-fixes/assets/InterfaceMethodSignatureError.ets +43 -0
- package/skills/arkts-error-fixes/assets/NotificationError.ets +34 -0
- package/skills/arkts-error-fixes/assets/ObjectLiteralInterfaceError.ets +49 -0
- package/skills/arkts-error-fixes/assets/ObjectLiteralTypeError.ets +54 -0
- package/skills/arkts-error-fixes/assets/ObjectSpreadError.ets +29 -0
- package/skills/arkts-error-fixes/assets/PossiblyNullError.ets +32 -0
- package/skills/arkts-error-fixes/assets/ResourceConversionError.ets +159 -0
- package/skills/arkts-error-fixes/assets/StandaloneFunctionContext.ets +116 -0
- package/skills/arkts-error-fixes/assets/StandaloneFunctionError.ets +85 -0
- package/skills/arkts-error-fixes/assets/StorageLinkDefaultError.ets +41 -0
- package/skills/arkts-error-fixes/assets/TitleButtonRectTypeError.ets +86 -0
- package/skills/arkts-error-fixes/assets/UnusedVariableWarning.ets +102 -0
- package/skills/arkts-error-fixes/assets/UtilityTypeError.ets +176 -0
- package/skills/arkts-error-fixes/assets/WindowRectSizeError.ets +65 -0
- package/skills/arkts-error-fixes/assets/WindowTypeError.ets +37 -0
- package/skills/arkts-error-fixes/reference/any_type_errors.md +433 -0
- package/skills/arkts-error-fixes/reference/appstorage_errors.md +95 -0
- package/skills/arkts-error-fixes/reference/arrow_function_conversion_errors.md +163 -0
- package/skills/arkts-error-fixes/reference/avoid_area_type_errors.md +59 -0
- package/skills/arkts-error-fixes/reference/breakpoint_type_errors.md +122 -0
- package/skills/arkts-error-fixes/reference/catch_clause_type_errors.md +89 -0
- package/skills/arkts-error-fixes/reference/color_consistency_errors.md +209 -0
- package/skills/arkts-error-fixes/reference/color_property_errors.md +136 -0
- package/skills/arkts-error-fixes/reference/context_type_errors.md +260 -0
- package/skills/arkts-error-fixes/reference/decorator_state_errors.md +109 -0
- package/skills/arkts-error-fixes/reference/display_listener_type_errors.md +149 -0
- package/skills/arkts-error-fixes/reference/duplicate_entry_errors.md +193 -0
- package/skills/arkts-error-fixes/reference/esobject_type_errors.md +110 -0
- package/skills/arkts-error-fixes/reference/fontcolor_property_errors.md +104 -0
- package/skills/arkts-error-fixes/reference/function_return_type_errors.md +194 -0
- package/skills/arkts-error-fixes/reference/idata_source_errors.md +77 -0
- package/skills/arkts-error-fixes/reference/implementation_not_allowed_errors.md +191 -0
- package/skills/arkts-error-fixes/reference/interface_method_signature_errors.md +143 -0
- package/skills/arkts-error-fixes/reference/notification_errors.md +110 -0
- package/skills/arkts-error-fixes/reference/object_literal_interface_errors.md +156 -0
- package/skills/arkts-error-fixes/reference/object_literal_type_errors.md +110 -0
- package/skills/arkts-error-fixes/reference/object_spread_errors.md +105 -0
- package/skills/arkts-error-fixes/reference/possibly_null_errors.md +156 -0
- package/skills/arkts-error-fixes/reference/resource_conversion_errors.md +154 -0
- package/skills/arkts-error-fixes/reference/standalone_function_errors.md +68 -0
- package/skills/arkts-error-fixes/reference/storage_link_default_errors.md +124 -0
- package/skills/arkts-error-fixes/reference/title_button_rect_type_errors.md +167 -0
- package/skills/arkts-error-fixes/reference/unused_variable_warnings.md +295 -0
- package/skills/arkts-error-fixes/reference/utility_type_errors.md +290 -0
- package/skills/arkts-error-fixes/reference/window_rect_size_errors.md +70 -0
- package/skills/arkts-error-fixes/reference/window_type_errors.md +95 -0
- package/skills/arkts-grammar-standards/SKILL.md +71 -0
- package/skills/arkts-grammar-standards/references/basic-syntax.md +103 -0
- package/skills/arkts-grammar-standards/references/restrictions.md +100 -0
- package/skills/arkts-grammar-standards/references/topic-aliases.json +93 -0
- package/skills/arkts-grammar-standards/references/ts-diff.md +108 -0
- package/skills/arkts-runtime-fix/SKILL.md +152 -0
- package/skills/arkts-runtime-fix/SKILL_CN.md +123 -0
- package/skills/arkts-runtime-fix/evals/evals.json +17 -0
- package/skills/arkts-runtime-fix/scripts/collect-hilog.mjs +116 -0
- package/skills/arkts-runtime-fix/scripts/collect-hilog.ts +115 -0
- package/skills/arkts-runtime-fix/scripts/fetch-faultlog.mjs +117 -0
- package/skills/arkts-runtime-fix/scripts/fetch-faultlog.ts +116 -0
- package/skills/arkts-runtime-fix/scripts/jscrash-report.mjs +149 -0
- package/skills/arkts-runtime-fix/scripts/parse-jscrash-log.mjs +126 -0
- package/skills/arkts-runtime-fix/scripts/parse-jscrash-log.ts +126 -0
- package/skills/arkts-runtime-fix/scripts/probe-faultlogger.mjs +160 -0
- package/skills/arkts-runtime-fix/scripts/probe-faultlogger.ts +160 -0
- package/skills/arkts-runtime-fix/scripts/shared/hdc.mjs +107 -0
- package/skills/arkts-runtime-fix/scripts/shared/hdc.ts +58 -0
- package/skills/arkts-runtime-fix/scripts/shared/jscrash-faultlogger.mjs +143 -0
- package/skills/arkts-runtime-fix/scripts/shared/jscrash-faultlogger.ts +148 -0
- package/skills/arkts-runtime-fix/scripts/shared/jscrash-parse.mjs +389 -0
- package/skills/arkts-runtime-fix/scripts/shared/jscrash-parse.ts +409 -0
- package/skills/arkts-runtime-fix/scripts/shared/utils.mjs +27 -0
- package/skills/arkts-runtime-fix/scripts/shared/utils.ts +27 -0
- package/skills/arkui-knowledge/SKILL.md +90 -0
- package/skills/arkui-knowledge/references/api-guardrails.md +60 -0
- package/skills/arkui-knowledge/references/common-mistakes.md +119 -0
- package/skills/arkui-knowledge/references/component-cookbook.md +135 -0
- package/skills/arkui-knowledge/references/ui-quality-checklist.md +36 -0
- package/skills/deveco-create-project/SKILL.md +144 -0
- package/skills/deveco-create-project/application/AppScope/app.json5 +10 -0
- package/skills/deveco-create-project/application/AppScope/resources/base/element/string.json +8 -0
- package/skills/deveco-create-project/application/AppScope/resources/base/media/background.png +0 -0
- package/skills/deveco-create-project/application/AppScope/resources/base/media/foreground.png +0 -0
- package/skills/deveco-create-project/application/AppScope/resources/base/media/layered_image.json +7 -0
- package/skills/deveco-create-project/application/build-profile.json5 +42 -0
- package/skills/deveco-create-project/application/code-linter.json5 +32 -0
- package/skills/deveco-create-project/application/entry/build-profile.json5 +33 -0
- package/skills/deveco-create-project/application/entry/hvigorfile.ts +7 -0
- package/skills/deveco-create-project/application/entry/obfuscation-rules.txt +23 -0
- package/skills/deveco-create-project/application/entry/oh-package.json5 +10 -0
- package/skills/deveco-create-project/application/entry/src/main/ets/entryability/EntryAbility.ets +63 -0
- package/skills/deveco-create-project/application/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +31 -0
- package/skills/deveco-create-project/application/entry/src/main/ets/pages/Index.ets +38 -0
- package/skills/deveco-create-project/application/entry/src/main/module.json5 +50 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/element/color.json +8 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/element/float.json +8 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/element/string.json +16 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/media/background.png +0 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/media/foreground.png +0 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/media/layered_image.json +7 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/media/startIcon.png +0 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/profile/backup_config.json +3 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/base/profile/main_pages.json +5 -0
- package/skills/deveco-create-project/application/entry/src/main/resources/dark/element/color.json +8 -0
- package/skills/deveco-create-project/application/hvigor/hvigor-config.json5 +23 -0
- package/skills/deveco-create-project/application/hvigorfile.ts +7 -0
- package/skills/deveco-create-project/application/oh-package.json5 +10 -0
- package/skills/deveco-create-project/scripts/copy-template.mjs +216 -0
- package/skills/deveco-create-project/scripts/copy-template.ts +214 -0
- package/skills/deveco-create-project/scripts/detect-sdk.mjs +82 -0
- package/skills/deveco-create-project/scripts/detect-sdk.ts +95 -0
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
# Any Type Errors
|
|
2
|
+
|
|
3
|
+
## Error: Use explicit types instead of "any", "unknown"
|
|
4
|
+
|
|
5
|
+
### Error Message
|
|
6
|
+
```
|
|
7
|
+
Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
### Cause
|
|
11
|
+
ArkTS requires explicit type definitions and does not allow the use of `any` or `unknown` types. This is part of ArkTS's stricter type system designed to improve type safety and reduce runtime errors.
|
|
12
|
+
|
|
13
|
+
### Solution
|
|
14
|
+
Use explicit type definitions, interfaces, type aliases, union types, or generics instead of `any` or `unknown`.
|
|
15
|
+
|
|
16
|
+
### Key Points
|
|
17
|
+
- ArkTS does not allow `any` or `unknown` types
|
|
18
|
+
- Use explicit types for all variables and parameters
|
|
19
|
+
- Define interfaces for complex object types
|
|
20
|
+
- Use union types for multiple possible types
|
|
21
|
+
- Use generics for reusable type-safe code
|
|
22
|
+
|
|
23
|
+
### ❌ Wrong Usage
|
|
24
|
+
```typescript
|
|
25
|
+
// ❌ Wrong: Using any type
|
|
26
|
+
let data: any = { name: 'John', age: 30 };
|
|
27
|
+
|
|
28
|
+
// ❌ Wrong: Using any in function parameters
|
|
29
|
+
function processData(input: any): void {
|
|
30
|
+
console.info(input.name);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ❌ Wrong: Using any in event handlers
|
|
34
|
+
function handleEvent(event: any): void {
|
|
35
|
+
console.info(event.target);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ❌ Wrong: Using unknown type
|
|
39
|
+
let value: unknown = 'Hello';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### ✅ Correct Usage
|
|
43
|
+
```typescript
|
|
44
|
+
// ✅ Correct: Using explicit type
|
|
45
|
+
let data: { name: string; age: number } = { name: 'John', age: 30 };
|
|
46
|
+
|
|
47
|
+
// ✅ Correct: Using interface
|
|
48
|
+
interface UserData {
|
|
49
|
+
name: string;
|
|
50
|
+
age: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function processData(input: UserData): void {
|
|
54
|
+
console.info(input.name);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ✅ Correct: Using explicit event type
|
|
58
|
+
function handleEvent(event: ClickEvent): void {
|
|
59
|
+
console.info(event.target.toString());
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Interface Definitions
|
|
64
|
+
|
|
65
|
+
#### Simple Interface
|
|
66
|
+
```typescript
|
|
67
|
+
interface UserData {
|
|
68
|
+
name: string;
|
|
69
|
+
age: number;
|
|
70
|
+
email?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@Component
|
|
74
|
+
struct UserComponent {
|
|
75
|
+
@State user: UserData = { name: 'John', age: 30 };
|
|
76
|
+
|
|
77
|
+
private displayUser(data: UserData): string {
|
|
78
|
+
return `${data.name}, ${data.age}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
build() {
|
|
82
|
+
Text(this.displayUser(this.user))
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### Nested Interface
|
|
88
|
+
```typescript
|
|
89
|
+
interface Address {
|
|
90
|
+
street: string;
|
|
91
|
+
city: string;
|
|
92
|
+
zipCode: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface User {
|
|
96
|
+
id: number;
|
|
97
|
+
name: string;
|
|
98
|
+
address: Address;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@Component
|
|
102
|
+
struct AddressComponent {
|
|
103
|
+
@State user: User = {
|
|
104
|
+
id: 1,
|
|
105
|
+
name: 'John',
|
|
106
|
+
address: { street: '123 Main St', city: 'New York', zipCode: '10001' }
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
private displayAddress(user: User): string {
|
|
110
|
+
return `${user.address.street}, ${user.address.city}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
build() {
|
|
114
|
+
Text(this.displayAddress(this.user))
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Union Types
|
|
120
|
+
|
|
121
|
+
#### Simple Union
|
|
122
|
+
```typescript
|
|
123
|
+
type StringOrNumber = string | number;
|
|
124
|
+
|
|
125
|
+
@Component
|
|
126
|
+
struct UnionExample {
|
|
127
|
+
@State value: StringOrNumber = 'Hello';
|
|
128
|
+
|
|
129
|
+
private displayValue(value: StringOrNumber): string {
|
|
130
|
+
if (typeof value === 'string') {
|
|
131
|
+
return value;
|
|
132
|
+
} else {
|
|
133
|
+
return value.toString();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
build() {
|
|
138
|
+
Text(this.displayValue(this.value))
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Complex Union
|
|
144
|
+
```typescript
|
|
145
|
+
type EventData = ClickEvent | TouchEvent | ScrollEvent;
|
|
146
|
+
|
|
147
|
+
@Component
|
|
148
|
+
struct EventExample {
|
|
149
|
+
private handleEvent(event: EventData): void {
|
|
150
|
+
if (event instanceof ClickEvent) {
|
|
151
|
+
console.info('Click event');
|
|
152
|
+
} else if (event instanceof TouchEvent) {
|
|
153
|
+
console.info('Touch event');
|
|
154
|
+
} else {
|
|
155
|
+
console.info('Scroll event');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
build() {
|
|
160
|
+
Column() {
|
|
161
|
+
Button('Click')
|
|
162
|
+
.onClick((event: ClickEvent) => this.handleEvent(event))
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Generics
|
|
169
|
+
|
|
170
|
+
#### Simple Generic
|
|
171
|
+
```typescript
|
|
172
|
+
@Component
|
|
173
|
+
struct GenericExample {
|
|
174
|
+
@State items: number[] = [1, 2, 3, 4, 5];
|
|
175
|
+
|
|
176
|
+
private findItem<T>(array: T[], predicate: (item: T) => boolean): T | undefined {
|
|
177
|
+
for (const item of array) {
|
|
178
|
+
if (predicate(item)) {
|
|
179
|
+
return item;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
build() {
|
|
186
|
+
Column() {
|
|
187
|
+
Button('Find Item')
|
|
188
|
+
.onClick(() => {
|
|
189
|
+
const found = this.findItem(this.items, (item) => item > 3);
|
|
190
|
+
console.info(`Found: ${found}`);
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Generic Class
|
|
198
|
+
```typescript
|
|
199
|
+
class Storage<T> {
|
|
200
|
+
private data: T[] = [];
|
|
201
|
+
|
|
202
|
+
add(item: T): void {
|
|
203
|
+
this.data.push(item);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
get(index: number): T | undefined {
|
|
207
|
+
return this.data[index];
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
find(predicate: (item: T) => boolean): T | undefined {
|
|
211
|
+
return this.data.find(predicate);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@Component
|
|
216
|
+
struct StorageExample {
|
|
217
|
+
private storage: Storage<number> = new Storage<number>();
|
|
218
|
+
|
|
219
|
+
aboutToAppear() {
|
|
220
|
+
this.storage.add(1);
|
|
221
|
+
this.storage.add(2);
|
|
222
|
+
this.storage.add(3);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
build() {
|
|
226
|
+
Column() {
|
|
227
|
+
Button('Get Item')
|
|
228
|
+
.onClick(() => {
|
|
229
|
+
const item = this.storage.get(0);
|
|
230
|
+
console.info(`Item: ${item}`);
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Type Guards
|
|
238
|
+
|
|
239
|
+
#### Discriminated Union
|
|
240
|
+
```typescript
|
|
241
|
+
interface StringData {
|
|
242
|
+
type: 'string';
|
|
243
|
+
value: string;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface NumberData {
|
|
247
|
+
type: 'number';
|
|
248
|
+
value: number;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
type Data = StringData | NumberData;
|
|
252
|
+
|
|
253
|
+
@Component
|
|
254
|
+
struct TypeGuardExample {
|
|
255
|
+
@State data: Data = { type: 'string', value: 'Hello' };
|
|
256
|
+
|
|
257
|
+
private processData(data: Data): string {
|
|
258
|
+
if (data.type === 'string') {
|
|
259
|
+
return data.value;
|
|
260
|
+
} else {
|
|
261
|
+
return data.value.toString();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
build() {
|
|
266
|
+
Text(this.processData(this.data))
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### Typeof Guard
|
|
272
|
+
```typescript
|
|
273
|
+
type Value = string | number | boolean;
|
|
274
|
+
|
|
275
|
+
@Component
|
|
276
|
+
struct TypeofExample {
|
|
277
|
+
@State value: Value = 'Hello';
|
|
278
|
+
|
|
279
|
+
private displayValue(value: Value): string {
|
|
280
|
+
if (typeof value === 'string') {
|
|
281
|
+
return `String: ${value}`;
|
|
282
|
+
} else if (typeof value === 'number') {
|
|
283
|
+
return `Number: ${value}`;
|
|
284
|
+
} else {
|
|
285
|
+
return `Boolean: ${value}`;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
build() {
|
|
290
|
+
Text(this.displayValue(this.value))
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Object Type
|
|
296
|
+
|
|
297
|
+
#### Using Object
|
|
298
|
+
```typescript
|
|
299
|
+
@Component
|
|
300
|
+
struct ObjectExample {
|
|
301
|
+
@State config: Object = { width: 100, height: 200 };
|
|
302
|
+
|
|
303
|
+
private applyConfig(config: Object): void {
|
|
304
|
+
console.info(JSON.stringify(config));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private logArgs(...args: Object[]): void {
|
|
308
|
+
args.forEach(arg => {
|
|
309
|
+
console.info(JSON.stringify(arg));
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
build() {
|
|
314
|
+
Column() {
|
|
315
|
+
Button('Apply Config')
|
|
316
|
+
.onClick(() => {
|
|
317
|
+
this.applyConfig(this.config);
|
|
318
|
+
this.logArgs('arg1', 42, { key: 'value' });
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Type Aliases
|
|
326
|
+
|
|
327
|
+
#### Simple Alias
|
|
328
|
+
```typescript
|
|
329
|
+
type UserId = number;
|
|
330
|
+
type UserName = string;
|
|
331
|
+
type UserEmail = string;
|
|
332
|
+
|
|
333
|
+
interface User {
|
|
334
|
+
id: UserId;
|
|
335
|
+
name: UserName;
|
|
336
|
+
email: UserEmail;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
@Component
|
|
340
|
+
struct AliasExample {
|
|
341
|
+
@State user: User = { id: 1, name: 'John', email: 'john@example.com' };
|
|
342
|
+
|
|
343
|
+
build() {
|
|
344
|
+
Text(`${this.user.name} (${this.user.id})`)
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### Function Alias
|
|
350
|
+
```typescript
|
|
351
|
+
type EventHandler = (event: ClickEvent) => void;
|
|
352
|
+
type ValueHandler = (value: string) => void;
|
|
353
|
+
|
|
354
|
+
@Component
|
|
355
|
+
struct FunctionAliasExample {
|
|
356
|
+
private onClick: EventHandler = (event: ClickEvent): void => {
|
|
357
|
+
console.info('Clicked');
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
private onInput: ValueHandler = (value: string): void => {
|
|
361
|
+
console.info(`Input: ${value}`);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
build() {
|
|
365
|
+
Column() {
|
|
366
|
+
Button('Click')
|
|
367
|
+
.onClick(this.onClick)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Common Patterns
|
|
374
|
+
|
|
375
|
+
#### Event Handlers
|
|
376
|
+
```typescript
|
|
377
|
+
type ClickHandler = (event: ClickEvent) => void;
|
|
378
|
+
type TouchHandler = (event: TouchEvent) => void;
|
|
379
|
+
type ScrollHandler = (event: ScrollEvent) => void;
|
|
380
|
+
|
|
381
|
+
@Component
|
|
382
|
+
struct EventHandlers {
|
|
383
|
+
private onClick: ClickHandler = (event: ClickEvent): void => {
|
|
384
|
+
console.info('Clicked');
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
private onTouch: TouchHandler = (event: TouchEvent): void => {
|
|
388
|
+
console.info('Touched');
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
build() {
|
|
392
|
+
Column() {
|
|
393
|
+
Button('Click')
|
|
394
|
+
.onClick(this.onClick)
|
|
395
|
+
}
|
|
396
|
+
.onTouch(this.onTouch)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
#### Data Processing
|
|
402
|
+
```typescript
|
|
403
|
+
interface DataProcessor<T, R> {
|
|
404
|
+
process(data: T): R;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
class StringProcessor implements DataProcessor<string, number> {
|
|
408
|
+
process(data: string): number {
|
|
409
|
+
return data.length;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
@Component
|
|
414
|
+
struct ProcessorExample {
|
|
415
|
+
private processor: DataProcessor<string, number> = new StringProcessor();
|
|
416
|
+
|
|
417
|
+
build() {
|
|
418
|
+
Text(`Length: ${this.processor.process('Hello')}`)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Best Practices
|
|
424
|
+
1. **Use explicit types**: Always define types explicitly
|
|
425
|
+
2. **Define interfaces**: Use interfaces for complex object types
|
|
426
|
+
3. **Use union types**: Use union types for multiple possible types
|
|
427
|
+
4. **Use generics**: Use generics for reusable type-safe code
|
|
428
|
+
5. **Use type guards**: Use type guards for runtime type checking
|
|
429
|
+
6. **Avoid any**: Never use `any` or `unknown` types
|
|
430
|
+
|
|
431
|
+
### Related Files
|
|
432
|
+
- [Code Example](../assets/AnyTypeError.ets)
|
|
433
|
+
- [ArkTS Type System](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-type-system)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# AppStorage Type Errors
|
|
2
|
+
|
|
3
|
+
## Error: `AppStorage.get()` type parameter issue
|
|
4
|
+
|
|
5
|
+
### Error Message
|
|
6
|
+
```
|
|
7
|
+
Type inference errors with `AppStorage.get()`
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
### Cause
|
|
11
|
+
`AppStorage.get()` requires explicit type parameters or should be replaced with `setOrCreate` for proper type inference. ArkTS has strict type checking for generic functions.
|
|
12
|
+
|
|
13
|
+
### Solution
|
|
14
|
+
Use `AppStorage.setOrCreate()` for initialization or provide explicit type parameters with `@StorageLink`.
|
|
15
|
+
|
|
16
|
+
### Key Points
|
|
17
|
+
- Use `@StorageLink('key')` decorator for type-safe state binding
|
|
18
|
+
- Initialize with `AppStorage.setOrCreate('key', value)` in `aboutToAppear()`
|
|
19
|
+
- The decorator automatically handles type inference
|
|
20
|
+
- State is synchronized across all components using the same key
|
|
21
|
+
|
|
22
|
+
### @StorageLink Pattern
|
|
23
|
+
```typescript
|
|
24
|
+
@Entry
|
|
25
|
+
@Component
|
|
26
|
+
struct MyComponent {
|
|
27
|
+
@StorageLink('myKey') myValue: number = 0;
|
|
28
|
+
|
|
29
|
+
aboutToAppear() {
|
|
30
|
+
AppStorage.setOrCreate('myKey', 0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
build() {
|
|
34
|
+
Text(`Value: ${this.myValue}`)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### AppStorage Methods
|
|
40
|
+
```typescript
|
|
41
|
+
// Set or create a value
|
|
42
|
+
AppStorage.setOrCreate<T>(key: string, value: T): T
|
|
43
|
+
|
|
44
|
+
// Get a value (requires type parameter)
|
|
45
|
+
AppStorage.get<T>(key: string): T | undefined
|
|
46
|
+
|
|
47
|
+
// Set a value
|
|
48
|
+
AppStorage.set<T>(key: string, value: T): void
|
|
49
|
+
|
|
50
|
+
// Delete a value
|
|
51
|
+
AppStorage.delete(key: string): void
|
|
52
|
+
|
|
53
|
+
// Check if key exists
|
|
54
|
+
AppStorage.has(key: string): boolean
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### State Decorators
|
|
58
|
+
```typescript
|
|
59
|
+
// Two-way binding with AppStorage
|
|
60
|
+
@StorageLink('key') value: Type = defaultValue;
|
|
61
|
+
|
|
62
|
+
// One-way binding with AppStorage
|
|
63
|
+
@StorageProp('key') value: Type = defaultValue;
|
|
64
|
+
|
|
65
|
+
// Two-way binding with LocalStorage
|
|
66
|
+
@LocalStorageLink('key') value: Type = defaultValue;
|
|
67
|
+
|
|
68
|
+
// One-way binding with LocalStorage
|
|
69
|
+
@LocalStorageProp('key') value: Type = defaultValue;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Best Practices
|
|
73
|
+
1. **Use @StorageLink**: Prefer decorators over direct AppStorage access
|
|
74
|
+
2. **Initialize properly**: Always call `setOrCreate` in `aboutToAppear()`
|
|
75
|
+
3. **Use unique keys**: Ensure keys are unique across the application
|
|
76
|
+
4. **Type safety**: Let the decorator handle type inference
|
|
77
|
+
5. **Clean up**: Delete values when no longer needed
|
|
78
|
+
|
|
79
|
+
### Common Patterns
|
|
80
|
+
```typescript
|
|
81
|
+
// Counter pattern
|
|
82
|
+
@StorageLink('counter') count: number = 0;
|
|
83
|
+
|
|
84
|
+
// User data pattern
|
|
85
|
+
@StorageLink('userName') userName: string = '';
|
|
86
|
+
|
|
87
|
+
// Settings pattern
|
|
88
|
+
@StorageLink('isDarkMode') isDarkMode: boolean = false;
|
|
89
|
+
|
|
90
|
+
// Object pattern
|
|
91
|
+
@StorageLink('userSettings') settings: UserSettings = defaultSettings;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Related Files
|
|
95
|
+
- [Code Example](../assets/AppStorageError.ets)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Function.bind 错误
|
|
2
|
+
|
|
3
|
+
## 错误描述
|
|
4
|
+
|
|
5
|
+
在 ArkTS 中,`Function.bind()` 方法不被支持。当尝试使用 `Function.bind()` 绑定 `this` 上下文时,会导致编译错误。
|
|
6
|
+
|
|
7
|
+
## 错误示例
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { mediaquery, UIContext } from '@kit.ArkUI';
|
|
11
|
+
|
|
12
|
+
@Entry
|
|
13
|
+
@Component
|
|
14
|
+
struct BindError {
|
|
15
|
+
@State isWideScreen: boolean = false;
|
|
16
|
+
private mediaListener: mediaquery.MediaQueryListener | null = null;
|
|
17
|
+
|
|
18
|
+
aboutToAppear() {
|
|
19
|
+
const mediaQuery = this.getUIContext().getMediaQuery();
|
|
20
|
+
this.mediaListener = mediaQuery.matchMediaSync('(min-width: 600vp)');
|
|
21
|
+
|
|
22
|
+
if (this.mediaListener) {
|
|
23
|
+
this.mediaListener.on('change', this.onMediaQueryChange.bind(this));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private onMediaQueryChange(result: mediaquery.MediaQueryResult): void {
|
|
28
|
+
this.isWideScreen = result.matches;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
build() {
|
|
32
|
+
Column() {
|
|
33
|
+
Text(`屏幕宽度: ${this.isWideScreen ? '宽屏' : '窄屏'}`)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**错误信息:**
|
|
40
|
+
```
|
|
41
|
+
Function.bind is not supported in ArkTS
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 解决方案
|
|
45
|
+
|
|
46
|
+
### 方案一:使用箭头函数
|
|
47
|
+
|
|
48
|
+
使用箭头函数替代 `Function.bind()`,箭头函数会自动捕获 `this` 上下文。
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
@Entry
|
|
52
|
+
@Component
|
|
53
|
+
struct ArrowFunctionSolution {
|
|
54
|
+
@State isWideScreen: boolean = false;
|
|
55
|
+
private mediaListener: mediaquery.MediaQueryListener | null = null;
|
|
56
|
+
|
|
57
|
+
aboutToAppear() {
|
|
58
|
+
const mediaQuery = this.getUIContext().getMediaQuery();
|
|
59
|
+
this.mediaListener = mediaQuery.matchMediaSync('(min-width: 600vp)');
|
|
60
|
+
|
|
61
|
+
if (this.mediaListener) {
|
|
62
|
+
this.mediaListener.on('change', (result: mediaquery.MediaQueryResult) => {
|
|
63
|
+
this.isWideScreen = result.matches;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
build() {
|
|
69
|
+
Column() {
|
|
70
|
+
Text(`屏幕宽度: ${this.isWideScreen ? '宽屏' : '窄屏'}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 方案二:使用内联箭头函数
|
|
77
|
+
|
|
78
|
+
如果需要调用其他方法,可以在箭头函数内部调用。
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
@Entry
|
|
82
|
+
@Component
|
|
83
|
+
struct InlineArrowFunctionSolution {
|
|
84
|
+
@State isWideScreen: boolean = false;
|
|
85
|
+
private mediaListener: mediaquery.MediaQueryListener | null = null;
|
|
86
|
+
|
|
87
|
+
aboutToAppear() {
|
|
88
|
+
const mediaQuery = this.getUIContext().getMediaQuery();
|
|
89
|
+
this.mediaListener = mediaQuery.matchMediaSync('(min-width: 600vp)');
|
|
90
|
+
|
|
91
|
+
if (this.mediaListener) {
|
|
92
|
+
this.mediaListener.on('change', (result: mediaquery.MediaQueryResult) => {
|
|
93
|
+
this.handleMediaQueryChange(result);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private handleMediaQueryChange(result: mediaquery.MediaQueryResult): void {
|
|
99
|
+
this.isWideScreen = result.matches;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
build() {
|
|
103
|
+
Column() {
|
|
104
|
+
Text(`屏幕宽度: ${this.isWideScreen ? '宽屏' : '窄屏'}`)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 简单示例
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
@Entry
|
|
114
|
+
@Component
|
|
115
|
+
struct ArrowFunctionExample {
|
|
116
|
+
@State count: number = 0;
|
|
117
|
+
|
|
118
|
+
build() {
|
|
119
|
+
Column() {
|
|
120
|
+
Text(`计数: ${this.count}`)
|
|
121
|
+
.fontSize(20)
|
|
122
|
+
.margin({ bottom: 16 })
|
|
123
|
+
|
|
124
|
+
Button('增加')
|
|
125
|
+
.onClick(() => {
|
|
126
|
+
this.count++;
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
.padding(16)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 详细代码示例
|
|
135
|
+
|
|
136
|
+
- [ArrowFunctionConversionError.ets](../assets/ArrowFunctionConversionError.ets) - 完整的 Function.bind 错误修复示例,包含媒体查询监听和箭头函数使用
|
|
137
|
+
|
|
138
|
+
## 最佳实践
|
|
139
|
+
|
|
140
|
+
1. **使用箭头函数**:在需要保留 `this` 上下文的地方,优先使用箭头函数
|
|
141
|
+
2. **避免 bind**:不要使用 `Function.bind()`,因为它在 ArkTS 中不被支持
|
|
142
|
+
3. **内联处理简单逻辑**:对于简单的逻辑,可以直接在箭头函数中处理
|
|
143
|
+
4. **提取复杂逻辑**:对于复杂的逻辑,可以提取为独立方法,然后在箭头函数中调用
|
|
144
|
+
|
|
145
|
+
## 常见错误
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// ❌ 错误:使用 Function.bind
|
|
149
|
+
this.mediaListener.on('change', this.onMediaQueryChange.bind(this));
|
|
150
|
+
|
|
151
|
+
// ❌ 错误:使用 Function.bind
|
|
152
|
+
button.onClick(this.handleClick.bind(this));
|
|
153
|
+
|
|
154
|
+
// ✅ 正确:使用箭头函数
|
|
155
|
+
this.mediaListener.on('change', (result: mediaquery.MediaQueryResult) => {
|
|
156
|
+
this.isWideScreen = result.matches;
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// ✅ 正确:使用箭头函数调用方法
|
|
160
|
+
button.onClick(() => {
|
|
161
|
+
this.handleClick();
|
|
162
|
+
});
|
|
163
|
+
```
|