The layout and prototype chain of Sendable objects are immutable, whereas the layout of non-Sendable objects can be modified through special means. Therefore, mutual inheritance is not allowed. Note that this rule applies to classes, not variables; a Sendable class cannot inherit from a variable.
Correct Example
@Sendable
class A {
constructor() {
}
}
@Sendable
class B extends A {
constructor() {
super()
}
} Incorrect Example
class A {
constructor() {
}
}
@Sendable
class B extends A { // A is not a Sendable class. B cannot inherit it. A compilation error is reported.
constructor() {
super()
}
} The layout and prototype chain of Sendable objects are immutable, whereas the layout of non-Sendable objects can be modified through special means. Therefore, mutual inheritance is not allowed.
Correct Example
class A {
constructor() {
}
}
class B extends A {
constructor() {
super()
}
} Incorrect Example
@Sendable
class A {
constructor() {
}
}
class B extends A { // A is a Sendable class. B cannot inherit it. A compilation error is reported.
constructor() {
super()
}
} If a non-Sendable class implements a Sendable interface, it may be mistakenly considered as Sendable, leading to incorrect usage.
Correct Example
interface I {};
class B implements I {}; Incorrect Example
import { lang } from '@kit.ArkTS';
type ISendable = lang.ISendable;
interface I extends ISendable {};
class B implements I {}; // I is a Sendable interface. B cannot implement it. A compilation error is reported. Sendable objects cannot hold non-Sendable data. Therefore, member properties of Sendable classes or interfaces must be of Sendable data types.
Correct Example
@Sendable
class A {
constructor() {
}
a: number = 0;
} Incorrect Example
@Sendable
class A {
constructor() {
}
b: Array<number> = [1, 2, 3] // A compilation error is reported. Use collections.Array instead.
} Member 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.
Correct Example
@Sendable
class A {
constructor() {
}
a: number = 0;
} Incorrect Example
@Sendable
class A {
constructor() {
}
a!: number; // A compilation error is reported. The exclamation mark (!) is not supported.
} The layout of Sendable objects is immutable. Computed properties cannot statically determine the object layout, and therefore they cannot be used for Sendable objects.
Correct Example
@Sendable
class A {
num1: number = 1;
num2: number = 2;
add(): number {
return this.num1 + this.num2;
}
} Incorrect Example
enum B {
b1 = "bbb"
}
@Sendable
class A {
["aaa"]: number = 1; // A compilation error is reported. ["aaa"] is not supported.
[B.b1]: number = 2; // A compilation error is reported. [B.b1] is not supported.
} Member variables of the Sendable class cannot use type aliases (that is, aliases defined using the type keyword).
Correct Example
@Sendable
class B {
num1: number = 1;
num2: number = 2;
add(): number {
return this.num1 + this.num2;
}
} Incorrect Example
type A = number;
@Sendable
class B {
num1: A = 1; // A runtime error is reported. Type aliases are not supported.
num2: A = 2; // A runtime error is reported. Type aliases are not supported.
add(): number {
return this.num1 + this.num2;
}
} Sendable objects cannot hold non-Sendable data. Therefore, template types for Sendable data in generic classes must be Sendable.
Correct Example
import { collections } from '@kit.ArkTS';
try {
let arr1: collections.Array<number> = new collections.Array<number>();
let num: number = 1;
arr1.push(num);
} catch (e) {
console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
} Incorrect Example
import { collections } from '@kit.ArkTS';
try {
let arr1: collections.Array<Array<number>> = new collections.Array<Array<number>>(); // A compilation error is reported. The template type must be Sendable.
let arr2: Array<number> = new Array<number>();
arr2.push(1);
arr1.push(arr2);
} catch (e) {
console.error(`taskpool execute: Code: ${e.code}, message: ${e.message}`);
} Sendable 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.
Since API version 12, Sendable classes can use top-level Sendable class objects.
Correct Example
import { lang } from '@kit.ArkTS';
type ISendable = lang.ISendable;
interface I extends ISendable {}
@Sendable
class B implements I {
static o: number = 1;
static bar(): B {
return new B();
}
}
@Sendable
class C {
v: I = new B();
u: number = B.o;
foo() {
return B.bar();
}
} Incorrect Example
import { lang } from '@kit.ArkTS';
type ISendable = lang.ISendable;
interface I extends ISendable {}
@Sendable
class B implements I {}
function bar(): B {
return new B();
}
let b = new B();
{
@Sendable
class A implements I {}
@Sendable
class C {
u: I = bar(); // bar is not a Sendable class object. A compile-time error is reported.
v: I = new A(); // A is not defined at the top level. A compile-time error is reported.
foo() {
return b; // b is not a Sendable class object but an instance of the Sendable class. A compile-time error is reported.
}
}
} Currently, only classes and functions can be decorated.
Correct Example
@Sendable
type SendableFuncType = () => void;
@Sendable
class C {}
@Sendable
function SendableFunc() {
console.info("Sendable func");
} Incorrect Example
@Sendable type A = number; // A compile-time error is reported. @Sendable type D = C; // A compile-time error is reported.
If a class decorator is defined in a .ts file, the class structure may be modified, causing runtime errors.
Correct Example
@Sendable
class A {
num: number = 1;
} Incorrect Example
@Sendable
@Observed // A compilation error is reported.
class C {
num: number = 1;
} Since API version 22, custom decorators other than @Sendable can be added to Sendable classes.
You can add the disableSendableCheckRules field to strictMode under the buildOption field in the project-level build-profile.json5 file.
The following is an example of the disableSendableCheckRules field and its value:
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true,
"disableSendableCheckRules": ["arkts-sendable-class-decorator"]
}
}
The value of disableSendableCheckRules is an array containing Sendable rules.
By default, this field is not displayed. That is, custom decorators other than @Sendable cannot be added to Sendable classes.
Configuring it as an empty array is prohibited.
When the arkts-sendable-class-decorator rule is configured in the array, custom decorators other than @Sendable can be added to Sendable classes.
Using @Sendable with other custom decorators may cause runtime exceptions. Therefore, you need to adapt the implementation of the decorator function.
Object literals and array literals are not Sendable types. Sendable data types must be created using new expressions of Sendable types.
Correct Example
import { collections } from '@kit.ArkTS';
let arr1: collections.Array<number> = new collections.Array<number>(1, 2, 3); // The type is Sendable. Incorrect Example
import { collections } from '@kit.ArkTS';
let arr2: collections.Array<number> = [1, 2, 3]; // The type is not Sendable. A compile-time error is reported.
let arr3: number[] = [1, 2, 3]; // The type is not Sendable. No error is reported.
let arr4: number[] = new collections.Array<number>(1, 2, 3); // A compile-time error is reported. Except for the Object type, non-Sendable types cannot be forcibly converted to Sendable types. 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.
Correct Example
class A {
state: number = 0;
}
@Sendable
class SendableA {
state: number = 0;
}
let a1: A = new SendableA() as A; Incorrect Example
class A {
state: number = 0;
}
@Sendable
class SendableA {
state: number = 0;
}
let a2: SendableA = new A() as SendableA; // A compilation error is reported. Arrow functions do not support the @Sendable decorator and are non-Sendable. Therefore, they cannot be shared.
Correct Example
@Sendable
type SendableFuncType = () => void;
@Sendable
function SendableFunc() {
console.info("Sendable func");
}
@Sendable
class SendableClass {
constructor(f: SendableFuncType) {
this.func = f;
}
func: SendableFuncType;
}
let sendableClass = new SendableClass(SendableFunc); Incorrect Example
@Sendable
type SendableFuncType = () => void;
let func: SendableFuncType = () => {}; // A compile-time error is reported.
@Sendable
class SendableClass {
func: SendableFuncType = () => {}; // A compile-time error is reported.
} | Rule |
|---|
| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when passing them to TS/JS interfaces. |
| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when setting them to TS/JS objects. |
| Do not modify the object layout (add or delete properties, or change property types) of Sendable objects when placing them in TS/JS containers. |
Changing the property type does not include changing the type of a Sendable object, such as from Sendable class A to Sendable class B.
For details about Node-APIs, see Sendable-related Operations. For details about how to use the Node-APIs, see Wrapping a Native Object in a Sendable ArkTS Object.
| Rule |
|---|
| Do not delete properties. Prohibited API: napi_delete_property. |
| Do not add properties. Prohibited APIs: napi_set_property, napi_set_named_property, and napi_define_properties. |
| Do not change the property type. Prohibited APIs: napi_set_property, napi_set_named_property, and napi_define_properties. |
| Do not use the Symbol-related APIs and types. Prohibited APIs: napi_create_symbol, napi_is_symbol_object and napi_symbol. |
To observe data changes in Sendable objects when interacting with UI, Sendable data must be used in conjunction with makeObserved. For more information, see Using makeObserved with @Sendable Decorated Classes.
Sendable can be used in HARs. When Sendable is used in a bytecode HAR, no additional configuration is required. When Sendable is used in a TS HAR, set name under metadata to UseTsHar in the module.json5 file of the HAR module. The configuration is as follows:
{
"module": {
"name": "library",
"type": "har",
"deviceTypes": [
"tablet",
"2in1"
],
"metadata": [
{
"name": "UseTsHar",
"value": "true"
}
]
}
}