1# Usage Rules and Constraints for Sendable 2 3## Sendable Classes Must Inherit Only from Other Sendable Classes 4 5The layout and prototype chain of Sendable objects are immutable. Non-Sendable objects can modify their layout in special ways, but they cannot inherit from or be inherited by Sendable classes. This rule applies to classes, not variables. In other words, Sendable classes cannot inherit from variables. 6 7**Correct Example** 8 9```ts 10@Sendable 11class A { 12 constructor() { 13 } 14} 15 16@Sendable 17class B extends A { 18 constructor() { 19 super() 20 } 21} 22``` 23 24**Incorrect Example** 25 26```ts 27class A { 28 constructor() { 29 } 30} 31 32@Sendable 33class B extends A { 34 constructor() { 35 super() 36 } 37} 38``` 39 40 41## Non-Sendable Classes Must Inherit Only from Other Non-Sendable Classes 42 43The layout and prototype chain of Sendable objects are immutable. Since non-Sendable objects can modify their layout in special ways, they cannot inherit from or be inherited by Sendable classes. 44 45**Correct Example** 46 47```ts 48class A { 49 constructor() { 50 } 51} 52 53class B extends A { 54 constructor() { 55 super() 56 } 57} 58``` 59 60**Incorrect Example** 61 62```ts 63@Sendable 64class A { 65 constructor() { 66 } 67} 68 69class B extends A { 70 constructor() { 71 super() 72 } 73} 74``` 75 76 77## Non-Sendable Classes Can Only Implement Non-Sendable Interfaces 78 79If a non-Sendable class implements a Sendable interface, it may be mistakenly considered as Sendable, leading to incorrect usage. 80 81**Correct Example** 82 83```ts 84interface I {}; 85 86class B implements I {}; 87``` 88 89**Incorrect Example** 90 91```ts 92import { lang } from '@kit.ArkTS'; 93 94type ISendable = lang.ISendable; 95 96interface I extends ISendable {}; 97 98class B implements I {}; 99``` 100 101 102## Member Variables of Sendable Classes/Interfaces Must Be Sendable Data Types 103 104Sendable objects cannot hold non-Sendable data. Therefore, member properties of Sendable objects must be of Sendable data types. 105 106**Correct Example** 107 108```ts 109@Sendable 110class A { 111 constructor() { 112 } 113 a: number = 0; 114} 115``` 116 117**Incorrect Example** 118 119```ts 120@Sendable 121class A { 122 constructor() { 123 } 124 b: Array<number> = [1, 2, 3] // collections.Array must be used. 125} 126``` 127 128 129## Member Variables of Sendable Classes/Interfaces Cannot Use the Exclamation Mark (!) for Assertion 130 131Member properties of Sendable objects must be initialized. The assertion using the exclamation mark (!) allows variables to remain uninitialized. Therefore, using the exclamation mark (!) for assertion is not supported. 132 133**Correct Example** 134 135```ts 136@Sendable 137class A { 138 constructor() { 139 } 140 a: number = 0; 141} 142``` 143 144**Incorrect Example** 145 146```ts 147@Sendable 148class A { 149 constructor() { 150 } 151 a!: number; 152} 153``` 154 155 156## Member Variables of Sendable Classes/Interfaces Cannot Use Computed Property Names 157 158The layout of Sendable objects is immutable. Computed properties cannot statically determine the object layout, and therefore they cannot be used for Sendable objects. 159 160**Correct Example** 161 162```ts 163@Sendable 164class A { 165 num1: number = 1; 166 num2: number = 2; 167 add(): number { 168 return this.num1 + this.num2; 169 } 170} 171``` 172 173**Incorrect Example** 174 175```ts 176enum B { 177 b1 = "bbb" 178} 179@Sendable 180class A { 181 ["aaa"]: number = 1; // ["aaa"] is allowed in other classes in ets files 182 [B.b1]: number = 2; // [B.b1] is allowed in other classes in ets files 183} 184``` 185 186 187## Template Types for Sendable Classes, collections.Array, collections.Map, and collections.Set Must Be Sendable 188 189Sendable objects cannot hold non-Sendable data. Therefore, template types for Sendable data in generic classes must be Sendable. 190 191**Correct Example** 192 193```ts 194import { collections } from '@kit.ArkTS'; 195 196try { 197 let arr1: collections.Array<number> = new collections.Array<number>(); 198 let num: number = 1; 199 arr1.push(num); 200} catch (e) { 201 console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`); 202} 203``` 204 205**Incorrect Example** 206 207```ts 208import { collections } from '@kit.ArkTS'; 209 210try { 211 let arr1: collections.Array<Array<number>> = new collections.Array<Array<number>>(); 212 let arr2: Array<number> = new Array<number>(); 213 arr2.push(1); 214 arr1.push(arr2); 215} catch (e) { 216 console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`); 217} 218``` 219 220 221## Sendable Classes Cannot Use Variables Defined in the Context of the Current Module 222 223Sendable objects operate in different concurrent instances with distinct context environments within a single virtual machine instance. Direct access to variables defined in the context of the current module can lead to unexpected behavior. Therefore, Sendable objects cannot use variables defined in the context of the current module. Violations will result in compile-time errors. 224 225> **NOTE** 226> 227> Since API version 12, Sendable classes can use top-level Sendable class objects. 228 229**Correct Example** 230 231```ts 232import { lang } from '@kit.ArkTS'; 233 234type ISendable = lang.ISendable; 235 236interface I extends ISendable {} 237 238@Sendable 239class B implements I { 240 static o: number = 1; 241 static bar(): B { 242 return new B(); 243 } 244} 245 246@Sendable 247class C { 248 v: I = new B(); 249 u: number = B.o; 250 251 foo() { 252 return B.bar(); 253 } 254} 255``` 256 257**Incorrect Example** 258 259```ts 260import { lang } from '@kit.ArkTS'; 261 262type ISendable = lang.ISendable; 263 264interface I extends ISendable {} 265 266@Sendable 267class B implements I {} 268 269function bar(): B { 270 return new B(); 271} 272 273let b = new B(); 274 275{ 276 @Sendable 277 class A implements I {} 278 279 @Sendable 280 class C { 281 u: I = bar(); // bar is not a Sendable class object. A compile-time error is reported. 282 v: I = new A(); // A is not defined at the top level. A compile-time error is reported. 283 284 foo() { 285 return b; // b is not a Sendable class object but an instance of the Sendable class. A compile-time error is reported. 286 } 287 } 288} 289``` 290 291 292## Sendable Classes and Functions Cannot Use Decorators Other Than @Sendable 293 294If a class decorator modifies the class layout and is defined in a .ts file, it can cause runtime errors. 295 296**Correct Example** 297 298```ts 299@Sendable 300class A { 301 num: number = 1; 302} 303``` 304 305**Incorrect Example** 306 307```ts 308@Sendable 309@Observed 310class C { 311 num: number = 1; 312} 313``` 314 315 316## Object Literals/Array Literals Cannot Be Used to Initialize Sendable Types 317 318Object literals and array literals are non-Sendable types. Sendable data types can only be created using **new** expressions of Sendable types. 319 320**Correct Example** 321 322```ts 323import { collections } from '@kit.ArkTS'; 324 325let arr1: collections.Array<number> = new collections.Array<number>(1, 2, 3); // The type is Sendable. 326``` 327 328**Incorrect Example** 329 330```ts 331import { collections } from '@kit.ArkTS'; 332 333let arr2: collections.Array<number> = [1, 2, 3]; // The type is not Sendable. A compile-time error is reported. 334let arr3: number[] = [1, 2, 3]; // The type is not Sendable. No error is reported. 335let arr4: number[] = new collections.Array<number>(1, 2, 3); // A compile-time error is reported. 336``` 337 338 339## Non-Sendable Types Cannot Be Cast to Sendable Types Using **as** 340 341Except for the Object type, non-Sendable types cannot be cast to Sendable types using **as**. Using **as** to cast a non-Sendable type to a Sendable type results in an object that is still non-Sendable, leading to incorrect usage. Sendable types, however, can be cast to non-Sendable types using **as** to maintain compatibility, provided they do not violate Sendable rules. 342 343**Correct Example** 344 345```ts 346class A { 347 state: number = 0; 348} 349 350@Sendable 351class SendableA { 352 state: number = 0; 353} 354 355let a1: A = new SendableA() as A; 356``` 357 358**Incorrect Example** 359 360```ts 361class A { 362 state: number = 0; 363} 364 365@Sendable 366class SendableA { 367 state: number = 0; 368} 369 370let a2: SendableA = new A() as SendableA; 371``` 372 373 374## Arrow Functions Are Not Supported for Sharing 375 376Arrow functions do not support the @Sendable decorator and are non-Sendable. Therefore, they cannot be shared. 377 378**Correct Example** 379 380```ts 381@Sendable 382type SendableFuncType = () => void; 383 384@Sendable 385function SendableFunc() { 386 console.info("Sendable func"); 387} 388 389@Sendable 390class SendableClass { 391 constructor(f: SendableFuncType) { 392 this.func = f; 393 } 394 func: SendableFuncType; 395} 396 397let sendableClass = new SendableClass(SendableFunc); 398``` 399 400**Incorrect Example** 401 402```ts 403@Sendable 404type SendableFuncType = () => void; 405let func: SendableFuncType = () => {}; // A compile-time error is reported. 406 407@Sendable 408class SendableClass { 409 func: SendableFuncType = () => {}; // A compile-time error is reported. 410} 411``` 412 413 414## @Sendable Can Only Be Applied to Function Types 415 416Currently, The @Sendable decorator only supports declaring Sendable function types. 417 418**Correct Example** 419 420```ts 421@Sendable 422type SendableFuncType = () => void; 423``` 424 425**Incorrect Example** 426 427```ts 428@Sendable 429type A = number; // A compile-time error is reported. 430 431@Sendable 432class C {} 433 434@Sendable 435type D = C; // A compile-time error is reported. 436``` 437 438 439## Notice 440 441 442When using Sendable in HAR, you must enable the configuration for compiling and generating TS files. For details, see [Building TS Files](../quick-start/har-package.md#building-ts-files). 443 444 445## Rules for Interaction with TS/JS 446 447 448### ArkTS General Rules (Only for Sendable Objects Currently) 449 450| Rule| 451| -------- | 452| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when passing them to TS/JS interfaces.| 453| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when setting them to TS/JS objects.| 454| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when placing them in TS/JS containers.| 455 456> **NOTE** 457> 458> Changing the property type does not include changing the type of a Sendable object, such as from Sendable class A to Sendable class B. 459 460 461### NAPI Rules (Only for Sendable Objects Currently) 462 463| Rule| 464| -------- | 465| Do not delete properties. Prohibited interfaces: **napi_delete_property**.| 466| Do not add properties. Prohibited interfaces: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| 467| Do not change property types. Prohibited interfaces: **napi_set_property**, **napi_set_named_property**, and **napi_define_properties**.| 468| Symbol-related interfaces and types are not supported. Prohibited interfaces: **napi_create_symbol**, **napi_is_symbol_object**, and **napi_symbol**.| 469 470 471## Rules for Interaction with the UI 472 473To observe data changes in Sendable objects when interacting with UI, Sendable data must be used in conjunction with [makeObserved](../quick-start/arkts-new-makeObserved.md). For more information, see [Using makeObserved and @Sendable Decorated Class Together](../quick-start/arkts-new-makeObserved.md#using-makeobserved-and-sendable-decorated-class-together). 474