TypeScript to ArkTS Cookbook
ArkTS restricts the features of TypeScript (TS) that undermine development correctness or increase runtime overhead. This topic lists the TypeScript features restricted by ArkTS and provides recipes on code refactoring. ArkTS retains most syntax features of TypeScript. TypeScript features that are not mentioned in this topic are fully supported by ArkTS. For example, the custom decorators supported by ArkTS have the same syntax as those supported by TypeScript. After code refactoring based on the recipes in this topic, the code is still valid TypeScript code.
Example
Original TypeScript code containing the keyword var:
function addTen(x: number): number {
var ten = 10;
return x + ten;
}
Refactored code:
function addTen(x: number): number {
let ten = 10;
return x + ten;
}
Severity levels
Each recipe is marked with the severity level.
- Error: The recipe should be followed, otherwise the program will fail to compile.
- Warning: It is highly recommended to follow the recipe. Although violating the recipe does not currently affect the compilation, in future versions, it will cause compilation to fail.
Unsupported Features
Currently, unsupported features are mainly either of the following:
- Features relate to dynamic typing that degrades runtime performance
- Features that require extra support in the compiler, thereby degrading project build time
However, the ArkTS team reserves the right to reconsider the list and shrink it in the future releases based on the feedback from developers and real-world data experiments.
Recipes Summarized
This topic lists the TypeScript features that are not supported or partially supported by ArkTS. For details about the full feature list, detailed code examples, and workaround suggestions, see Recipes. For more cases, see Adaptation Cases.
Static Typing Is Enforced
One of the most important features of ArkTS is static typing. If a program is statically typed (all types are known at compile time), it is much easier to understand what data structures are used in the code. Since all types are known before the program actually runs, the compiler can verify code correctness, thereby eliminating many runtime type checks and improving performance.
Therefore, the usage of the type any in ArkTS is prohibited.
Example
// Not supported:
let res: any = some_api_function('hello', 'world');
// Supported:
class CallResult {
public succeeded(): boolean {
return false;
}
public errorMessage(): string {
return '123';
}
}
function some_api_function(param1: string, param2: string): CallResult {
return new CallResult();
}
let res: CallResult = some_api_function('hello', 'world');
if (!res.succeeded()) {
console.info('Call failed: ' + res.errorMessage());
}
According to our measurements, any is already not welcome in TypeScript. It is used in approximately 1% of TypeScript codebases. Moreover, today's code linters (for example, ESLint) include a set of rules that prohibit the usage of any. Prohibiting any results in a strong positive impact on performance at the cost of low-effort code refactoring.
Changing Object Layout in Runtime Is Prohibited
To achieve maximum performance benefits, ArkTS requires the layout of objects to remain unchanged during program execution. In other words, it is prohibited to:
- Add new properties or methods to objects.
- Delete existing properties or methods from objects.
- Assign values of arbitrary types to object properties.
It is noteworthy that many such operations are already prohibited by the TS compiler. However, it can still be "tricked" by, for example, using as any to convert the object type, disabling strict type check when compiling TS code, or ignoring type check using @ts-ignore in the code.
In ArkTS, strict type check is not configurable. ArkTS enforces strict type check and prohibits the use of any and @ts-ignore in the code.
Example
class Point {
public x: number = 0
public y: number = 0
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
// It is impossible to delete a property from the object. It is guaranteed that all Point objects have the property x.
let p1 = new Point(1.0, 1.0);
delete p1.x; // Compile-time error in TypeScript and ArkTS
delete (p1 as any).x; // OK in TypeScript; compile-time error in ArkTS
// Class Point does not define any property named `z`, and it is impossible to add it while the program runs.
let p2 = new Point(2.0, 2.0);
p2.z = 'Label'; // Compile-time error in TypeScript and ArkTS
(p2 as any).z = 'Label'; // OK in TypeScript; compile-time error in ArkTS
// It is guaranteed that all Point objects have only properties x and y and other properties cannot be added.
let p3 = new Point(3.0, 3.0);
let prop = Symbol(); // OK in TypeScript; compile-time error in ArkTS
(p3 as any)[prop] = p3.x; // OK in TypeScript; compile-time error in ArkTS
p3[prop] = p3.x; // Compile-time error in TypeScript and ArkTS
// It is guaranteed that all Point objects have properties x and y of type number, so assigning a value of any other type is impossible:
let p4 = new Point(4.0, 4.0);
p4.x = 'Hello!'; // Compile-time error in TypeScript and ArkTS
(p4 as any).x = 'Hello!'; // OK in TypeScript; compile-time error in ArkTS
// Usage of Point objects which are compliant with the class definition:
function distance(p1: Point, p2: Point): number {
return Math.sqrt(
(p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y)
);
}
let p5 = new Point(5.0, 5.0);
let p6 = new Point(6.0, 6.0);
console.info('Distance between p5 and p6: ' + distance(p5, p6));
Unpredictable changing of object layout contradicts both good readability and good performance of code. Indeed, having class definition at one place and modifying actual object layout elsewhere is confusing and error-prone from the developer's point of view. It opposes the idea of static typing and requires extra runtime support that causes undesired execution overhead. When an explicit type is used, properties cannot be added or deleted.
Currently, only a few projects allow object layout changes at runtime, and some common code linters have added corresponding constraints. Although a small amount of code refactoring is required, the performance improvement benefits are considerable.
Semantics of Operators Is Restricted
To achieve better performance and encourage developers to write clearer code, ArkTS restricts the semantics of some operators. An example is given below, and the full list of constraints is outlined in Recipes.
Example
// Unary `+` is defined only for numbers, but not for strings:
let t = +42; // OK
let s = +'42'; // Compile-time error
Loading language operators with extra semantics complicates the language specification, and forces developers to remember all possible corner cases with appropriate handling rules. Besides, in certain cases it causes some undesired runtime overhead.
According to our observations and experiments, this feature is not popular in TypeScript. It is used in less than 1% of real-world codebases, and such cases are easy to refactor. Restricting the operator semantics results in a clearer and more performant at the cost of low-effort changes in code.
Structural Typing Is Not Supported
Assume that two unrelated classes T and U have the same public API:
class T {
public name: string = ''
public greet(): void {
console.info('Hello, ' + this.name);
}
}
class U {
public name: string = ''
public greet(): void {
console.info('Greetings, ' + this.name);
}
}
Can we assign a value of T to a variable of U?
let u: U = new T(); // Is this allowed?
Can we pass a value of T to a function that accepts a parameter of U?
function greeter(u: U) {
console.info('To ' + u.name);
u.greet();
}
let t: T = new T();
greeter(t); // Is this allowed?
In other words, which approach will we take:
- T and U are not related by inheritance or any common interface, but they are "somewhat equivalent" since they have the same public API, and so the answer to both questions above is "yes".
- T and U are not related by inheritance or any common interface, and always must be considered as totally different types, and so the answer to both questions above is "no".
The languages that take the first approach are said to support structural typing, whereas the languages that take the second approach do not support it. Currently, TypeScript supports structural typing, and ArkTS does not.
It is debatable whether structural typing helps to produce code that is clearer and more understandable, and both pro and contra arguments can be found. Why not just support it then?
The answer is that supporting structural typing is a major feature that needs a lot of considerations and careful implementation in language specification, compiler, and runtime. More importantly, in case if ArkTS, which enforces static typing (see above), runtime support for structural typing implies performance overhead.
So since functionally correct and performant implementation requires taking that many aspects into account, the support to this feature is postponed. The ArkTS team is ready to reconsider based on real-world scenarios and feedback. More cases and suggested workarounds can be found in Recipes.
Recipes
Objects with Property Names That Are Not Identifiers Are Not Supported
Rule: arkts-identifiers-as-prop-names
Severity: error
Error code: 10605001
ArkTS does not support objects with name properties that are numbers or strings. Exceptions are string type enumeration constants and string literal. Use classes to access data by property names. Use arrays to access data by numeric indices.
TypeScript
var x = { 'name': 'x', 2: '3' };
console.info(x['name']); // x
console.info(x[2]); // 3
ArkTS
class X {
public name: string = '';
}
let x: X = { name: 'x' };
console.info(x.name); // x
let y = ['a', 'b', 'c'];
console.info(y[2]); // c
// Use Map<Object, some_type> in scenarios where data needs to be obtained using non-identifier keys (that is, keys of different types).
let z = new Map<Object, string>();
z.set('name', '1');
z.set(2, '2');
console.info(z.get('name')); // 1
console.info(z.get(2)); // 2
enum Test {
A = 'aaa',
B = 'bbb'
};
let obj: Record<string, number> = {
[Test.A]: 1, // string value in the enumeration
[Test.B]: 2, // string value in the enumeration
['value']: 3 // string literal
};
Symbol() Is Not Supported
Rule: arkts-no-symbol
Severity: error
Error code: 10605002
ArkTS does not support the Symbol() API because its most popular use cases make no sense in the statically typed environment. In particular, the object layout is defined at compile time and cannot be changed at runtime.
Only Symbol.iterator is supported.
Private # Identifiers Are Not Supported
Rule: arkts-no-private-identifiers
Severity: error
Error code: 10605003
ArkTS does not use private identifiers starting with the symbol #. Use the keyword private instead.
TypeScript
class C {
#foo: number = 42
}
ArkTS
class C {
private foo: number = 42;
}
Use Unique Names for Types and Namespaces
Rule: arkts-unique-names
Severity: error
Error code: 10605004
Names for all types (classes, interfaces, and enums) and namespaces must be unique and distinct from other names such as, variable names, and function names.
TypeScript
let X: string
type X = number[] // Type alias with the same name as the variable
ArkTS
let X: string;
type T = number[] // X is not allowed here to avoid name collisions.
Use let Instead of var
Rule: arkts-no-var
Severity: error
Error code: 10605005
The let keyword can declare variables in block scope, helping programmers avoid errors. Therefore, ArkTS does not support var. Use let instead.
TypeScript
function f(shouldInitialize: boolean) {
if (shouldInitialize) {
var x = 'b';
}
return x;
}
console.info(f(true)); // b
console.info(f(false)); // undefined
let upperLet = 0;
{
var scopedVar = 0;
let scopedLet = 0;
upperLet = 5;
}
scopedVar = 5; // Visible
scopedLet = 5; // Compile-time error
ArkTS
function f(shouldInitialize: boolean): string {
let x: string = 'a';
if (shouldInitialize) {
x = 'b';
}
return x;
}
console.info(f(true)); // b
console.info(f(false)); // a
let upperLet = 0;
let scopedVar = 0;
{
let scopedLet = 0;
upperLet = 5;
}
scopedVar = 5;
scopedLet = 5; // Compile-time error
Use Explicit Types Instead of any or unknown
Rule: arkts-no-any-unknown
Severity: error
Error code: 10605008
ArkTS does not support the types any and unknown. Specify types explicitly.
TypeScript
let value1: any
value1 = true;
value1 = 42;
let value2: unknown
value2 = true;
value2 = 42;
ArkTS
let valueB: boolean = true; // Or let valueB = true.
let valueN: number = 42; // Or let valueN = 42.
let valueO1: Object = true;
let valueO2: Object = 42;
Use class Instead of a Type with a Call Signature
Rule: arkts-no-call-signatures
Severity: error
Error code: 10605014
ArkTS does not support call signatures in object types. Use class instead.
TypeScript
type DescribableFunction = {
description: string
(someArg: string): string // call signature
}
function doSomething(fn: DescribableFunction): void {
console.info(fn.description + ' returned ' + fn(''));
}
ArkTS
class DescribableFunction {
public description: string;
public invoke(someArg: string): string {
return someArg;
}
constructor() {
this.description = 'desc';
}
}
function doSomething(fn: DescribableFunction): void {
console.info(fn.description + ' returned ' + fn.invoke(''));
}
doSomething(new DescribableFunction());
Use class Instead of a Type with a Constructor Signature
Rule: arkts-no-ctor-signatures-type
Severity: error
Error code: 10605015
ArkTS does not support constructor signatures in object types. Use class instead.
TypeScript
class SomeObject { }
type SomeConstructor = {
new(s: string): SomeObject
}
function fn(ctor: SomeConstructor) {
return new ctor('hello');
}
ArkTS
class SomeObject {
public f: string;
constructor (s: string) {
this.f = s;
}
}
function fn(s: string): SomeObject {
return new SomeObject(s);
}
Only One Static Block Is Supported
Rule: arkts-no-multiple-static-blocks
Severity: error
Error code: 10605016
ArkTS does not allow several static blocks for class initialization. Combine static block statements into one static block.
TypeScript
class C {
static s: string
static {
C.s = 'aa'
}
static {
C.s = C.s + 'bb'
}
}
ArkTS
class C {
public static s: string;
static {
C.s = 'aa';
C.s = C.s + 'bb';
}
}
Indexed Signatures Are Not Supported
Rule: arkts-no-indexed-signatures
Severity: error
Error code: 10605017
ArkTS does not allow indexed signatures. Use arrays instead.
TypeScript
// Interface with an indexed signature:
interface StringArray {
[index: number]: string
}
function getStringArray(): StringArray {
return ['a', 'b', 'c'];
}
const myArray: StringArray = getStringArray();
const secondItem = myArray[1];
ArkTS
class X {
public f: string[] = [];
}
let myArray: X = new X();
const secondItem = myArray.f[1];
Use Inheritance Instead of Intersection Types
Rule: arkts-no-intersection-types
Severity: error
Error code: 10605019
Currently, ArkTS does not support intersection types. Use inheritance as a workaround.
TypeScript
interface Identity {
id: number
name: string
}
interface Contact {
email: string
phoneNumber: string
}
type Employee = Identity & Contact
ArkTS
interface Identity {
id: number;
name: string;
}
interface Contact {
email: string;
phoneNumber: string;
}
interface Employee extends Identity, Contact {}
Type Notation Using this Is Not Supported
Rule: arkts-no-typing-with-this
Severity: error
Error code: 10605021
ArkTS does not support type notation using the this keyword. Use the explicit type instead.
TypeScript
interface ListItem {
getHead(): this
}
class C {
n: number = 0
m(c: this) {
// ...
}
}
ArkTS
interface testListItem {
getHead(): testListItem;
}
class C {
public n: number = 0;
m(c: C) {
// ...
}
}
Conditional Types Are Not Supported
Rule: arkts-no-conditional-types
Severity: error
Error code: 10605022
ArkTS does not support conditional type aliases. Introduce a new type with constraints explicitly, or rewrite logic using Object.
The keyword infer is not supported.
TypeScript
type X<T> = T extends number ? T : never;
type Y<T> = T extends Array<infer Item> ? Item : never;
ArkTS
// Provide explicit constraints within type alias.
type X1<T extends number> = T;
// Rewrite with Object. Less type control requires more type checking for safety.
type X2<T> = Object;
// Item must be used as a generic parameter and can be instantiated correctly.
type YI<Item, T extends Array<Item>> = Item;
Declaring Fields in constructor Is Not Supported
Rule: arkts-no-ctor-prop-decls
Severity: error
Error code: 10605025
ArkTS does not support declaring class fields in constructor. Explicitly declare class fields inside the class scope instead.
TypeScript
class Person {
constructor(
protected ssn: string,
private firstName: string,
private lastName: string
) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return this.firstName + ' ' + this.lastName;
}
}
ArkTS
class Person {
protected ssn: string;
private firstName: string;
private lastName: string;
constructor(ssn: string, firstName: string, lastName: string) {
this.ssn = ssn;
this.firstName = firstName;
this.lastName = lastName;
}
getFullName(): string {
return this.firstName + ' ' + this.lastName;
}
}
Constructor Signatures Are Not Supported in Interfaces
Rule: arkts-no-ctor-signatures-iface
Severity: error
Error code: 10605027
ArkTS does not allow constructor signatures to be defined in interfaces. Use common functions or methods instead.
TypeScript
interface I {
new(s: string): I;
}
function fn(i: I) {
return new i('hello');
}
ArkTS
interface I {
create(s: string): I;
}
function fn(i: I) {
return i.create('hello');
}
Indexed Access Types Are Not Supported
Rule: arkts-no-aliases-by-index
Severity: error
Error code: 10605028
ArkTS does not support indexed access types. Use the type name instead.
Indexed Access Is Not Supported for Fields
Rule: arkts-no-props-by-index
Severity: error
Error code: 10605029
ArkTS does not support dynamic field declaration and access. Access only those class fields that are either declared in the class, or accessible via inheritance. Accessing any other fields is prohibited, and causes compile-time errors.
To access a field, use the obj.field syntax. Indexed access (obj['field']) is not supported.
An exception is all typed arrays from the standard library (for example, Int32Array), which support access to their elements through the container[index] syntax.
TypeScript
class Point {
x: string = '';
y: string = '';
}
let p: Point = { x: '1', y: '2' };
console.info(p['x']); // 1
class Person {
name: string = '';
age: number = 0;
[key: string]: string | number;
}
let person: Person = {
name: 'John',
age: 30,
email: '***@example.com',
phoneNumber: '18*********',
}
ArkTS
class Point {
x: string = ''
y: string = ''
}
let p: Point = {x: '1', y: '2'};
console.info(p.x); // 1
class Person {
name: string
age: number
email: string
phoneNumber: string
constructor(name: string, age: number, email: string,
phoneNumber: string) {
this.name = name;
this.age = age;
this.email = email;
this.phoneNumber = phoneNumber;
}
}
let person = new Person('John', 30, '***@example.com', '18*********');
console.info(person['name']); // Compile-time error
console.info(person.unknownProperty); // Compile-time error
let arr = new Int32Array(1);
arr[0];
Structural Typing Is Not Supported
Rule: arkts-no-structural-typing
Severity: error
Error code: 10605030
Currently, ArkTS does not support structural typing. This means that the compiler cannot compare public APIs of two types and decide whether they are identical. Use other mechanisms (inheritance, interfaces, or type aliases) instead.
TypeScript
interface I1 {
f(): string
}
interface I2 { // I2 is structurally equivalent to I1.
f(): string
}
class X {
n: number = 0
s: string = ''
}
class Y { // Y is structurally equivalent to X.
n: number = 0
s: string = ''
}
let x = new X();
let y = new Y();
// Assign the X object to the Y object.
y = x;
// Assign the Y object to the X object.
x = y;
function foo(x: X) {
console.info(x.n + x.s);
}
// X and Y are equivalent because their public API is equivalent.
foo(new X());
foo(new Y());
ArkTS
interface I1 {
f(): string
}
type I2 = I1 // I2 is an alias for I1.
class B {
n: number = 0
s: string = ''
}
// D is derived from B, which explicitly set subtype/supertype relations.
class D extends B {
constructor() {
super()
}
}
let b = new B();
let d = new D();
console.info('Assign D to B');
b = d; // OK. B is the superclass of D.
// An attempt to assign b to d will result in a compile-time error.
// d = b
interface Z {
n: number
s: string
}
// X implements interface Z, which makes relationship between X and Y explicit.
class X implements Z {
n: number = 0
s: string = ''
}
// Y implements interface Z, which makes relationship between X and Y explicit.
class Y implements Z {
n: number = 0
s: string = ''
}
let x: Z = new X();
let y: Z = new Y();
console.info('Assign X to Y');
y = x // OK, both are of the same type
console.info('Assign Y to X');
x = y // OK, both are of the same type
function foo(c: Z): void {
console.info(c.n + c.s);
}
// X and Y implement the same interface. Therefore both calls are allowed.
foo(new X());
foo(new Y());
Type Inference in Case of Generic Function Calls Is Limited
**Rule: **arkts-no-inferred-generic-params
Severity: error
Error code: 10605034
ArkTS allows to omit generic type parameters if it is possible to infer the concrete types from the parameters passed to the function. A compile-time error occurs otherwise.
In particular, inference of generic type parameters based only on function return types is prohibited.
TypeScript
function choose<T>(x: T, y: T): T {
return Math.random() < 0.5 ? x: y;
}
let x = choose(10, 20); // OK. choose<number>(...) is inferred.
let y = choose('10', 20); // Compile-time error
function greet<T>(): T {
return 'Hello' as T;
}
let z = greet() // Type of T is inferred as "unknown".
ArkTS
function choose<T>(x: T, y: T): T {
return Math.random() < 0.5 ? x: y;
}
let x = choose(10, 20); // OK. choose<number>(...) is inferred.
let y = choose('10', 20); // Compile-time error
function greet<T>(): T {
return 'Hello' as T;
}
let z = greet<string>();
Object Literal Must Correspond to Some Explicitly Declared Class or Interface
Rule: arkts-no-untyped-obj-literals
Severity: error
Error code: 10605038
ArkTS supports usage of object literals if the compiler can infer to the classes or interfaces that such literals correspond to. Otherwise, a compile-time error occurs. In some scenarios, the compiler can infer the type of the literal based on the context.
Using literals to initialize classes and interfaces is specifically not supported in the following contexts:
- Initialization of anything that has any, Object, or object type
- Initialization of classes or interfaces with methods
- Initialize a class that contains a custom constructor with parameters.
- Initialization of classes with readonly fields
Example 1
TypeScript
let o1 = { n: 42, s: 'foo' };
let o2: Object = { n: 42, s: 'foo' };
let o3: object = { n: 42, s: 'foo' };
let oo: Object[] = [{ n: 1, s: '1' }, { n: 2, s: '2' }];
ArkTS
class C1 {
public n: number = 0;
public s: string = '';
}
let o1: C1 = {n: 42, s: 'foo'};
let o2: C1 = {n: 42, s: 'foo'};
let o3: C1 = {n: 42, s: 'foo'};
let oo: C1[] = [{n: 1, s: '1'}, {n: 2, s: '2'}];
Example 2
TypeScript
class C2 {
s: string;
constructor(s: string) {
this.s = 's =' + s;
}
}
let o4: C2 = { s: 'foo' };
ArkTS
class C2 {
public s: string;
constructor(s: string) {
this.s = 's =' + s;
}
}
let o4 = new C2('foo');
Example 3
TypeScript
class C3 {
readonly n: number = 0;
readonly s: string = '';
}
let o5: C3 = { n: 42, s: 'foo' };
ArkTS
class C3 {
public n: number = 0;
public s: string = '';
}
let o5: C3 = {n: 42, s: 'foo'};
Example 4
TypeScript
abstract class A { }
let o6: A = {};
ArkTS
abstract class A {}
class C extends A {}
let o6: C = {}; // Or let o6: C = new C()
Example 5
TypeScript
class C4 {
n: number = 0;
s: string = '';
f() {
console.info('Hello');
}
}
let o7: C4 = { n: 42, s: 'foo', f: () => { } };
ArkTS
class C4 {
public n: number = 0;
public s: string = '';
f() {
console.info('Hello');
}
}
let o7 = new C4();
o7.n = 42;
o7.s = 'foo';
Example 6
TypeScript
class Point {
x: number = 0;
y: number = 0;
}
function getPoint(o: Point): Point {
return o;
}
// Because TS supports structural typing, p is inferred to be of type Point.
let p = { x: 5, y: 10 };
getPoint(p);
// The object literal is inferred to be of type Point from the context.
getPoint({ x: 5, y: 10 });
ArkTS
class Point {
public x: number = 0;
public y: number = 0;
// Use constructor() to create a valid object before literal initialization.
// Because no constructor is defined for Point, the compiler automatically adds a default constructor.
}
function getPoint(o: Point): Point {
return o;
}
// Explicitly define the type for literal initialization.
let p: Point = {x: 5, y: 10};
getPoint(p);
// getPoint accepts the Point type, and literal initialization creates a new Point instance.
getPoint({x: 5, y: 10});
Object Literals Cannot Be Used as Type Declarations
Rule: arkts-no-obj-literals-as-types
Severity: error
Error code: 10605040
ArkTS does not support the usage of object literals to declare types in place. Use classes or interfaces to declare types instead.
TypeScript
let o: { x: number, y: number } = {
x: 2,
y: 3
}
type S = Set<{ x: number, y: number }>
ArkTS
class O {
public x: number = 0;
public y: number = 0;
}
let o: O = {x: 2, y: 3};
type S = Set<O>;
Array Literals Must Contain Elements of Only Inferrable Types
Rule: arkts-no-noninferrable-arr-literals
Severity: error
Error code: 10605043
Basically, ArkTS infers the type of an array literal as a union type of its contents. However, a compile-time error occurs if there is at least one element with a non-inferrable type (for example, untyped object literal).
TypeScript
let a = [{ n: 1, s: '1' }, { n: 2, s: '2' }];
ArkTS
class C {
public n: number = 0
public s: string = ''
}
let a1 = [{n: 1, s: '1'} as C, {n: 2, s: '2'} as C]; // a1 is of type "C[]".
let a2: C[] = [{n: 1, s: '1'}, {n: 2, s: '2'}]; // a2 is of type "C[]".
Use Arrow Functions Instead of Function Expressions
Rule: arkts-no-func-expressions
Severity: error
Error code: 10605046
ArkTS does not support function expressions. Use arrow functions instead to specify explicitly.
TypeScript
let f = function (s: string) {
console.info(s);
}
ArkTS
let f = (s: string) => {
console.info(s);
}
Class Literals Are Not Supported
Rule: arkts-no-class-literals
Severity: error
Error code: 10605050
ArkTS does not support class literals. Introduce new named class types explicitly.
TypeScript
const Rectangle = class {
constructor(height: number, width: number) {
this.height = height;
this.width = width;
}
height;
width;
}
const rectangle = new Rectangle(0.0, 0.0);
ArkTS
class TestRectangle {
constructor(testHeight: number, testWidth: number) {
this.testHeight = testHeight;
this.testWidth = testWidth;
}
public testHeight: number;
public testWidth: number;
}
const rectangle = new TestRectangle(0.0, 0.0);
Classes Cannot Be Specified in the implements Clause
Rule: arkts-implements-only-iface
Severity: error
Error code: 10605051
ArkTS does not allow to specify a class in the implements clause. Only interfaces may be specified.
TypeScript
class C {
foo() { }
}
class C1 implements C {
foo() { }
}
ArkTS
interface C {
foo(): void
}
class C1 implements C {
foo() {}
}
Reassigning Object Methods Is Not Supported
Rule: arkts-no-method-reassignment
Severity: error
Error code: 10605052
ArkTS does not support reassigning a method for objects. In the statically typed languages, the layout of objects is fixed and all instances of the same object must share the same code of each method.
If you need to add specific behavior for certain objects, you can create separate wrapper functions or use inheritance.
TypeScript
class C {
foo() {
console.info('foo');
}
}
function bar() {
console.info('bar');
}
let c1 = new C();
let c2 = new C();
c2.foo = bar;
c1.foo(); // foo
c2.foo(); // bar
ArkTS
class C {
foo() {
console.info('foo');
}
}
class Derived extends C {
foo() {
console.info('Extra');
super.foo();
}
}
function bar() {
console.info('bar');
}
let c1 = new C();
let c2 = new C();
c1.foo(); // foo
c2.foo(); // foo
let c3 = new Derived();
c3.foo(); // Extra foo
Only the as T Syntax Is Supported for Type Casting
Rule: arkts-as-casts
Severity: error
Error code: 10605053
ArkTS supports the keyword as as the only syntax for type casting. Incorrect casting causes a compile-time error or runtime ClassCastException. The <type> syntax for type casting is not supported.
Use the expression new instead of as if a primitive type (such as a number or a boolean) must be cast to the reference type.
TypeScript
class testShape { }
class testCircle extends testShape { x: number = 5 }
class testSquare extends testShape { y: string = 'a' }
function createShape(): testShape {
return new testCircle();
}
let c1 = <testCircle>createShape();
let c2 = createShape() as testCircle;
// If the conversion is incorrect, no compile-time or runtime error is reported.
let c3 = createShape() as testSquare;
console.info(c3.y); // undefined
// In TS, since the `as` keyword does not take effect at runtime, the left operand of `instanceof` is not boxed into a reference type at runtime.
let e1 = (5.0 as Number) instanceof Number; // false
// A Number object is created and instanceof works as expected.
let e2 = (new Number(5.0)) instanceof Number; // true
ArkTS
class TestShape {}
class TestCircle extends TestShape { public x: number = 5 }
function createShape(): TestShape {
return new TestCircle();
}
let c1 = createShape() as TestCircle;
// A Number object is created and instanceof works as expected.
let e1 = (new Number(5.0)) instanceof Number; // true
JSX Expressions Are Not Supported
Rule: arkts-no-jsx
Severity: error
Error code: 10605054
Do not use JSX since no alternative is provided to rewrite it.
Unary Operators +, -, and ~ Work Only on Numbers
Rule: arkts-no-polymorphic-unops
Severity: error
Error code: 10605055
ArkTS allows unary operators to work on numeric types only. A compile-time error occurs if these operators are applied to a non-numeric type. Unlike in TypeScript, implicit casting of strings in this context is not supported and casting must be done explicitly.
TypeScript
let a = +5; // 5 as number
let b = +'5'; // 5 as number
let c = -5; // -5 as number
let d = -'5'; // -5 as number
let e = ~5; // -6 as number
let f = ~'5'; // -6 as number
let g = +'string'; // NaN as number
function returnTen(): string {
return '-10';
}
function returnString(): string {
return 'string';
}
let x = +returnTen(); // -10 as number
let y = +returnString(); // NaN
ArkTS
let a = +5; // 5 as number
let b = +'5'; // Compile-time error
let c = -5; // -5 as number
let d = -'5'; // Compile-time error
let e = ~5; // -6 as number
let f = ~'5'; // Compile-time error
let g = +'string'; // Compile-time error
function returnTen(): string {
return '-10';
}
function returnString(): string {
return 'string';
}
let x = +returnTen(); // Compile-time error
let y = +returnString(); // Compile-time error
delete Operator Is Not Supported
Rule: arkts-no-delete
Severity: error
Error code: 10605059
ArkTS assumes that object layout is known at compile time and cannot be changed at runtime. Therefore, the operation of deleting a property makes no sense.
TypeScript
class Point {
x?: number = 0.0;
y?: number = 0.0;
}
let p = new Point();
delete p.y;
ArkTS
// A nullable type can be declared, with null used as the default value.
class Point {
public x: number | null = 0;
public y: number | null = 0;
}
let p = new Point();
p.y = null;
typeof Operator Is Allowed Only in Expression Contexts
Rule: arkts-no-type-query
Severity: error
Error code: 10605060
ArkTS supports the typeof operator only in the expression context. Using typeof to specify type notations is not supported.
TypeScript
let n1 = 42;
let s1 = 'foo';
console.info(typeof n1); // 'number'
console.info(typeof s1); // 'string'
let n2: typeof n1;
let s2: typeof s1;
ArkTS
let n1 = 42;
let s1 = 'foo';
console.info(typeof n1); // 'number'
console.info(typeof s1); // 'string'
let n2: number;
let s2: string;
instanceof Operator Is Partially Supported
Rule: arkts-instanceof-ref-types
Severity: error
Error code: 10605065
In TypeScript, the left-hand side of an instanceof expression must be of the type any, an object type, or a type parameter. Otherwise, the result is false. In ArkTS, the left-hand side of an expression may be of any reference type, for example, an object, an array, or a function. Otherwise, a compile-time error occurs. In addition, the left operand in ArkTS cannot be a type. It must be an object instance.
TypeScript
let num: number = 42;
let result = num instanceof Number;
console.info('result = ', result); // result = false
ArkTS
let num: number = 42;
let result = num instanceof Number; // Compile-time error
in Operator Is Not Supported
Rule: arkts-no-in
Severity: error
Error code: 10605066
ArkTS does not support the operator in. This operator makes little sense since the object layout is known at compile time and cannot be changed at runtime. Use instanceof as a workaround if you want to check whether certain class members exist.
TypeScript
class Person {
name: string = '';
}
let p = new Person();
let b = 'name' in p; // true
ArkTS
class Person {
public name: string = '';
}
let p = new Person();
let b = p instanceof Person; // True. "name" is guaranteed to be present.
Destructuring Assignment Is Not Supported
Rule: arkts-no-destruct-assignment
Severity: error
Error code: 10605069
ArkTS does not support destructuring assignment. Use other idioms (for example, a temporary variable, where applicable) instead.
TypeScript
let [one, two] = [1, 2]; // Semicolon is required here.
[one, two] = [two, one];
let head, tail;
[head, ...tail] = [1, 2, 3, 4];
ArkTS
let arr: number[] = [1, 2];
let one = arr[0];
let two = arr[1];
let tmp = one;
one = two;
two = tmp;
let data: Number[] = [1, 2, 3, 4];
let head = data[0];
let tail: Number[] = [];
for (let i = 1; i < data.length; ++i) {
tail.push(data[i]);
}
Comma Operator Is Supported Only in for Loops
Rule: arkts-no-comma-outside-loops
Severity: error
Error code: 10605071
ArkTS supports the comma operator (,) only in for loops. In other cases, the comma operator is useless as it makes the execution order harder to understand.
NOTE
- This is different from the comma separator used to declare variables and pass function parameters.
TypeScript
for (let i = 0, j = 0; i < 10; ++i, j += 2) {
// ...
}
let x = 0;
x = (++x, x++); // 1
ArkTS
for (let i = 0, j = 0; i < 10; ++i, j += 2) {
// ...
}
// Use the explicit execution order instead of the comma operator.
let x = 0;
++x;
x = x++;
Destructuring Variable Declarations Are Not Supported
Rule: arkts-no-destruct-decls
Severity: error
Error code: 10605074
ArkTS does not support destructuring variable declarations. This is a dynamic feature relying on structural compatibility. In addition, names in destructuring declarations must be equal to properties within destructed classes.
TypeScript
class Point {
x: number = 0.0;
y: number = 0.0;
}
function returnZeroPoint(): Point {
return new Point();
}
let { x, y } = returnZeroPoint();
ArkTS
class Point {
public x: number = 0.0;
public y: number = 0.0;
}
function returnZeroPoint(): Point {
return new Point();
}
// Create local variables to process each field.
let zp = returnZeroPoint();
let x = zp.x;
let y = zp.y;
Type Annotation in the Catch Clause Is Not Supported
Rule: arkts-no-types-in-catch
Severity: error
Error code: 10605079
In TypeScript, the catch clause variable type annotation must be any or unknown if specified. As ArkTS does not support these types, omit type annotations.
TypeScript
try {
// ...
} catch (a: unknown) {
// Handle exceptions.
}
ArkTS
try {
// ...
} catch (a) {
// Handle exceptions.
}
for .. in Is Not Supported
Rule: arkts-no-for-in
Severity: error
Error code: 10605080
ArkTS does not support iteration over object contents by the for ... in loop. For objects, iteration over properties at runtime is considered redundant because object layout is known at compile time and cannot change at runtime.
TypeScript
let a: string[] = ['1.0', '2.0', '3.0'];
for (let i in a) {
console.info(a[i]);
}
ArkTS
let a: string[] = ['1.0', '2.0', '3.0'];
for (let i = 0; i < a.length; ++i) {
console.info(a[i]);
}
Mapped Type Expression Is Not Supported
Rule: arkts-no-mapped-types
Severity: error
Error code: 10605083
ArkTS does not support mapped types. Use other language idioms and regular classes to achieve the same behavior.
TypeScript
type OptionsFlags<Type> = {
[Property in keyof Type]: boolean
}
ArkTS
class C {
public n: number = 0;
public s: string = '';
}
class CFlags {
public n: boolean = false;
public s: boolean = false;
}
with Statement Is Not Supported
Rule: arkts-no-with
Severity: error
Error code: 10605084
ArkTS does not support the with statement. Use other language idioms to achieve the same behavior.
TypeScript
with (Math) { // Compile-time error, but JavaScript code can still be emitted.
let r: number = 42;
let area: number = PI * r * r;
}
ArkTS
let r: number = 42;
let area: number = Math.PI * r * r;
throw Statements Do Not Accept Values of Arbitrary Types
Rule: arkts-limited-throw
Severity: error
Error code: 10605087
ArkTS supports throwing only objects of the class Error or any derived class. Throwing an arbitrary type (for example, number or string) is prohibited.
TypeScript
throw 4;
throw '';
throw new Error();
ArkTS
throw new Error();
Function Return Type Inference Is Limited
Rule: arkts-no-implicit-return-types
Severity: error
Error code: 10605090
ArkTS supports type inference for function return types, but this functionality is currently restricted. In particular, when the expression in the return statement is a call to a function or method whose return value type is omitted, a compile-time error occurs. If this is the case, specify the return type explicitly.
TypeScript
// Compile-time error only when noImplicitAny is enabled.
function f(x: number) {
if (x <= 0) {
return x;
}
return g(x);
}
// Compile-time error only when noImplicitAny is enabled.
function g(x: number) {
return f(x - 1);
}
function doOperation(x: number, y: number) {
return x + y;
}
f(10);
doOperation(2, 3);
ArkTS
// An explicit return type is required.
function f(x: number): number {
if (x <= 0) {
return x;
}
return g(x);
}
// The return type can be omitted because it can be inferred from the type annotation of f.
function g(x: number): number {
return f(x - 1);
}
// Return type may be omitted.
function doOperation(x: number, y: number) {
return x + y;
}
f(10);
doOperation(2, 3);
Destructuring Parameter Declarations Are Not Supported
Rule: arkts-no-destruct-params
Severity: error
Error code: 10605091
ArkTS requires that arguments be explicitly passed to function parameters without destructing.
TypeScript
function drawText({ text = '', location: [x, y] = [0, 0], bold = false }) {
text;
x;
y;
bold;
}
drawText({ text: 'Hello, world!', location: [100, 50], bold: true });
ArkTS
function drawText(text: String, location: number[], bold: boolean) {
let x = location[0];
let y = location[1];
text;
x;
y;
bold;
}
function main() {
drawText('Hello, world!', [100, 50], true);
}
Nested Functions Are Not Supported
Rule: arkts-no-nested-funcs
Severity: error
Error code: 10605092
ArkTS does not support nested functions. Use lambdas instead.
TypeScript
function addNum(a: number, b: number): void {
// Nested function.
function logToConsole(message: string): void {
console.info(message);
}
let result = a + b;
// Invoke the nested function.
logToConsole('result is ' + result);
}
ArkTS
function addNum(a: number, b: number): void {
// Use lambda instead of a nested function.
let logToConsole: (message: string) => void = (message: string): void => {
console.info(message);
}
let result = a + b;
logToConsole('result is ' + result);
}
Using this Inside Stand-Alone Functions Is Not Supported
Rule: arkts-no-standalone-this
Severity: error
Error code: 10605093
ArkTS does not support the usage of this inside stand-alone functions and inside static methods. this can be used in instance methods only.
TypeScript
function foo(i: string) {
this.count = i; // Compile-time error only when noImplicitThis is enabled.
}
class A {
count: string = 'a';
m = foo;
}
let a = new A();
console.info(a.count); // Print "a".
a.m('b');
console.info(a.count); // Print "b".
ArkTS
class A {
public count: string = 'a'
m(i: string): void {
this.count = i;
}
}
function main(): void {
let a = new A();
console.info(a.count); // Print "a".
a.m('b');
console.info(a.count); // Print "b".
}
Generator Functions Are Not Supported
Rule: arkts-no-generators
Severity: error
Error code: 10605094
Currently, ArkTS does not support generator functions. Use the async or await mechanism for multitasking.
TypeScript
function* counter(start: number, end: number) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for (let num of counter(1, 5)) {
console.info(num.toString());
}
ArkTS
async function complexNumberProcessing(num: number): Promise<number> {
// ...
return num;
}
async function foo() {
for (let i = 1; i <= 5; i++) {
await complexNumberProcessing(i);
}
}
foo();
Type Guarding Is Supported with instanceof and as
Rule: arkts-no-is
Severity: error
Error code: 10605096
In ArkTS, the is keyword is not supported, and the instanceof operator must be used instead. Note that the fields of an object must be cast to the appropriate type with the as operator before instanceof is used.
TypeScript
class Foo {
foo: string = ''
common: string = ''
}
class Bar {
bar: string = ''
common: string = ''
}
function isFoo(arg: any): arg is Foo {
return arg.foo !== undefined;
}
function doStuff(arg: Foo | Bar) {
if (isFoo(arg)) {
console.info(arg.foo); // OK
console.info(arg.bar); // Compile-time error
} else {
console.info(arg.foo); // Compile-time error
console.info(arg.bar); // OK
}
}
doStuff({ foo: '123', common: '123' });
doStuff({ bar: '123', common: '123' });
ArkTS
class Foo {
foo: string = ''
common: string = ''
}
class Bar {
bar: string = ''
common: string = ''
}
function isFoo(arg: Object): boolean {
return arg instanceof Foo;
}
function doStuff(arg: Object): void {
if (isFoo(arg)) {
let fooArg = arg as Foo;
console.info(fooArg.foo); // OK
console.info(arg.bar); // Compile-time error
} else {
let barArg = arg as Bar;
console.info(arg.foo); // Compile-time error
console.info(barArg.bar); // OK
}
}
function main(): void {
doStuff(new Foo());
doStuff(new Bar());
}
Spread Operator Is Supported in Partial Scenarios
Rule: arkts-no-spread
Severity: error
Error code: 10605099
The only supported scenario for the spread operator is to spread an array, a child class of an array, or a typed array (for example, Int32Array). A spread operator can be used only in the following scenarios:
- Being passed to the rest parameter;
- Copying an array to an array literal.
TypeScript
function foo(x: number, y: number, z: number) {
// ...
}
let args: [number, number, number] = [0, 1, 2];
foo(...args);
ArkTS
function logNumbers(x: number, y: number, z: number) {
// ...
}
let numbers: number[] = [1, 2, 3];
logNumbers(numbers[0], numbers[1], numbers[2]);
TypeScript
let point2d = { x: 1, y: 2 };
let point3d = { ...point2d, z: 3 };
ArkTS
class Point2D {
public x: number = 0;
public y: number = 0;
}
class Point3D {
public x: number = 0;
public y: number = 0;
public z: number = 0
constructor(p2d: Point2D, z: number) {
this.x = p2d.x;
this.y = p2d.y;
this.z = z;
}
}
let p3d = new Point3D({ x: 1, y: 2 } as Point2D, 3);
class DerivedFromArray extends Uint16Array {};
let arr1 = [1, 2, 3];
let arr2 = new Uint16Array([4, 5, 6]);
let arr3 = new DerivedFromArray([7, 8, 9]);
let arr4 = [...arr1, 10, ...arr2, 11, ...arr3];
Interface Cannot Extend Interfaces with the Same Method
Rule: arkts-no-extend-same-prop
Severity: error
Error code: 106050102
In TypeScript, an interface that extends two other interfaces with the same method must declare that method with a combined return type. It is not allowed in ArkTS because ArkTS does not allow an interface to contain two methods with signatures that are not distinguishable, for example, two methods that have the same parameter lists but different return types.
TypeScript
interface Mover {
getStatus(): { speed: number }
}
interface Shaker {
getStatus(): { frequency: number }
}
interface MoverShaker extends Mover, Shaker {
getStatus(): {
speed: number
frequency: number
}
}
class C implements MoverShaker {
private speed: number = 0
private frequency: number = 0
getStatus() {
return { speed: this.speed, frequency: this.frequency };
}
}
ArkTS
class MoveStatus {
public speed: number;
constructor() {
this.speed = 0;
}
}
interface Mover {
getMoveStatus(): MoveStatus
}
class ShakeStatus {
public frequency: number;
constructor() {
this.frequency = 0;
}
}
interface Shaker {
getShakeStatus(): ShakeStatus
}
class MoveAndShakeStatus {
public speed: number;
public frequency: number;
constructor() {
this.speed = 0;
this.frequency = 0;
}
}
class C implements Mover, Shaker {
private moveStatus: MoveStatus;
private shakeStatus: ShakeStatus;
constructor() {
this.moveStatus = new MoveStatus();
this.shakeStatus = new ShakeStatus();
}
public getMoveStatus(): MoveStatus {
return this.moveStatus;
}
public getShakeStatus(): ShakeStatus {
return this.shakeStatus;
}
public getStatus(): MoveAndShakeStatus {
return {
speed: this.moveStatus.speed,
frequency: this.shakeStatus.frequency
};
}
}
Declaration Merging Is Not Supported
Rule: arkts-no-decl-merging
Severity: error
Error code: 10605103
ArkTS does not support merging declarations. Keep all definitions of classes and interfaces compact in the codebase.
TypeScript
interface Document {
createElement(tagName: any): number;
}
interface Document {
createElement(tagName: string): boolean;
}
interface Document {
createElement(tagName: number): number;
createElement(tagName: boolean): boolean;
createElement(tagName: string, value: number): string;
}
ArkTS
interface Document {
createElement(tagName: number): number;
createElement(tagName: boolean): boolean;
createElement(tagName: string, value: number): number;
createElement(tagName: string): string;
createElement(tagName: Object): object;
}
Interfaces Cannot Extend Classes
Rule: arkts-extends-only-class
Severity: error
Error code: 10605104
ArkTS does not support interfaces that extend classes. Interfaces can extend only interfaces.
TypeScript
class Control {
state: number = 0;
}
interface SelectableControl extends Control {
select(): void
}
ArkTS
interface Control {
state: number
}
interface SelectableControl extends Control {
select(): void
}
Constructor Function Type Is Not Supported
Rule: arkts-no-ctor-signatures-funcs
Severity: error
Error code: 10605106
ArkTS does not support the usage of the constructor function type. Use lambdas instead.
TypeScript
class Person {
constructor(
name: string,
age: number
) { }
}
type PersonCtor = new (name: string, age: number) => Person;
function createPerson(Ctor: PersonCtor, name: string, age: number): Person {
return new Ctor(name, age);
}
const person = createPerson(Person, 'John', 30);
ArkTS
class Person {
constructor(
name: string,
age: number
) {}
}
type PersonCtor = (n: string, a: number) => Person
function createPerson(ctor: PersonCtor, n: string, a: number): Person {
return ctor(n, a);
}
let impersonate: PersonCtor = (n: string, a: number): Person => {
return new Person(n, a);
}
const person = createPerson(impersonate, 'John', 30);
Enumeration Members Can Be Initialized Only with Compile Time Expressions of the Same Type
Rule: arkts-no-enum-mixed-types
Severity: error
Error code: 10605111
ArkTS does not support initializing members of enumerations with expressions that are evaluated during program runtime. Besides, all explicitly set initializers must be of the same type.
TypeScript
enum E1 {
A = 0xa,
B = 0xb,
C = Math.random(),
D = 0xd,
E // 0xe inferred.
}
enum E2 {
A = 0xa,
B = '0xb',
C = 0xc,
D = '0xd'
}
ArkTS
enum E1 {
A = 0xa,
B = 0xb,
C = 0xc,
D = 0xd,
E // 0xe inferred.
}
enum E2 {
A = '0xa',
B = '0xb',
C = '0xc',
D = '0xd'
}
enum Declaration Merging Is Not Supported
Rule: arkts-no-enum-merging
Severity: error
Error code: 10605113
ArkTS does not support merging declarations for enum. Keep the declaration of each enum compact in the codebase.
TypeScript
enum ColorSet {
RED,
GREEN
}
enum ColorSet {
YELLOW = 2
}
enum ColorSet {
BLACK = 3,
BLUE
}
ArkTS
enum ColorSet {
RED,
GREEN,
YELLOW,
BLACK,
BLUE
}
Namespaces Cannot Be Used as Objects
Rule: arkts-no-ns-as-obj
Severity: error
Error code: 10605114
ArkTS does not support the usage of namespaces as objects. Classes or modules can be interpreted as analogs of namespaces.
TypeScript
namespace MyNamespace {
export let x: number;
}
let m = MyNamespace;
m.x = 2;
ArkTS
namespace MyNamespace {
export let x: number;
}
MyNamespace.x = 2;
Non-declaration Statements in Namespaces Are Not Supported
Rule: arkts-no-ns-statements
Severity: error
Error code: 10605116
In ArkTS, namespaces are used to define the visibility scope of identifiers. Namespaces are valid only during compilation. Therefore, non-declaration statements are not supported in namespaces. Use a function to execute non-declaration statements.
TypeScript
namespace A {
export let x: number;
x = 1;
}
ArkTS
namespace A {
export let x: number
export function init() {
x = 1;
}
}
// Call the initialization function.
A.init();
require and import Assignment Are Not Supported
Rule: arkts-no-require
Severity: error
Error code: 10605121
ArkTS does not support importing via require. It does not support import assignments either. Use the regular import syntax instead.
TypeScript
import m = require('mod')
ArkTS
import * as m from './ExportMod'
export = ... Is Not Supported
Rule: arkts-no-export-assignment
Severity: error
Error code: 10605126
ArkTS does not support the export = ... syntax. Use the ordinary export and import syntaxes instead.
TypeScript
// module1
export = Point
class Point {
constructor(x: number, y: number) {}
static origin = new Point(0, 0)
}
// module2
import Pt = require('module1')
let p = Pt.Point.origin;
ArkTS
// ExportMod.ets
export class Point {
constructor(x: number, y: number) {}
public static origin = new Point(0, 0)
}
// module2
import * as Pt from './ExportMod'
let p = Pt.Point.origin;
Ambient Module Declaration Is Not Supported
Rule: arkts-no-ambient-decls
Severity: error
Error code: 10605128
ArkTS does not support ambient module declaration because it has its own mechanisms for interoperating with JavaScript.
TypeScript
declare module 'someModule' {
export function normalize(s: string): string;
}
ArkTS
// Import what you need from the original module.
import { normalize } from './ExportMod'
Wildcards in Module Names Are Not Supported
Rule: arkts-no-module-wildcards
Severity: error
Error code: 10605129
ArkTS does not support wildcards in module names because import is a compile-time feature in ArkTS, not a runtime feature.
TypeScript
// Declaration
declare module '*!text' {
const content: string
export default content
}
// Consuming code
import fileContent from 'some.txt!text'
ArkTS
// Declaration
export declare namespace N {
function foo(x: number): number
}
// Consuming code
import * as m from './ExportMod'
console.info('N.foo called: ' + m.N.foo(42));
UMD Is Not Supported
Rule: arkts-no-umd
Severity: error
Error code: 10605130
ArkTS does not support universal module definitions (UMD), because it does not have the concept of "script" (as opposed to "module"). In addition, import is a compile-time feature in ArkTS, not a runtime feature. Use the ordinary export and import syntaxes instead.
TypeScript
// math-lib.d.ts
export const isPrime(x: number): boolean
export as namespace mathLib
// In script
mathLib.isPrime(2)
ArkTS
// math-lib.d.ts
namespace mathLib {
export isPrime(x: number): boolean
}
// In program
import { mathLib } from 'math-lib'
mathLib.isPrime(2)
new.target Is Not Supported
Rule: arkts-no-new-target
Severity: error
Error code: 10605132
ArkTS does not support new.target because there is no concept of runtime prototype inheritance in the language. This feature is considered not applicable to static typing.
Definite Assignment Assertions Are Not Supported
Rule: arkts-no-definite-assignment
Severity: warning
Error code: 10605134
ArkTS does not support definite assignment assertions let v!: T because they are considered an excessive compiler hint. Use declarations with initialization instead.
TypeScript
let x!: number // Hint: x will be initialized before usage.
initialize();
function initialize() {
x = 10;
}
console.info('x = ' + x);
ArkTS
function initialize(): number {
return 10;
}
let x: number = initialize();
console.info('x = ' + x);
Prototype Assignment Is Not Supported
Rule: arkts-no-prototype-assignment
Severity: error
Error code: 10605136
ArkTS does not support prototype assignment because there is no concept of runtime prototype inheritance in the language. This feature is considered not applicable to static typing.
TypeScript
let C = function (p) {
this.p = p; // Compile-time error only when noImplicitThis is enabled.
}
C.prototype = {
m() {
console.info(this.p);
}
}
C.prototype.q = function (r: string) {
return this.p == r;
}
ArkTS
class C {
public p: string = '';
m() {
console.info(this.p);
}
q(r: string) {
return this.p === r;
}
}
globalThis Is Not Supported
Rule: arkts-no-globalthis
Severity: warning
Error code: 10605137
ArkTS does not support dynamic changes to the layout of objects. Therefore, global scope and globalThis are not supported.
TypeScript
// Global file.
var abc = 100;
// Reference 'abc'.
let x = globalThis.abc;
ArkTS
// ExportMod.ets
export let abc: number = 100;
// NoGlobalThis.ets
import * as M from './ExportMod'
let x = M.abc;
Some Utility Types Are Not Supported
Rule: arkts-no-utility-types
Severity: error
Error code: 10605138
ArkTS supports only Partial, Required, Readonly, and Record, and does not support other utility types in TypeScript.
For the Partial<T> type, the generic parameter T must be a class or interface type.
For objects of the Record type, the type of the value accessed using an index is a union type that contains undefined.
Declaring Properties on Functions Is Not Supported
Rule: arkts-no-func-props
Severity: error
Error code: 10605139
ArkTS does not support dynamic change of function object layout. Therefore, declaring properties on functions is not supported.
Function.apply and Function.call Are Not Supported
Rule: arkts-no-func-apply-call
Severity: error
Error code: 10605152
ArkTS does not support Function.apply or Function.call because these APIs are needed in the standard library to explicitly set the parameter this for the called function. In ArkTS, the semantics of this is restricted to the conventional OOP style, and the usage of this in function body is prohibited.
Function.bind Is Not Supported
Rule: arkts-no-func-bind
Severity: warning
Error code: 10605140
ArkTS does not support Function.bind. These APIs are needed in the standard library to explicitly set the parameter this for the called function. In ArkTS, the semantics of this is restricted to the conventional OOP style, and the usage of this in function body is prohibited.
as const Assertions Are Not Supported
Rule: arkts-no-as-const
Severity: error
Error code: 10605142
ArkTS does not support as const assertions and literal types. In standard TypeScript, as const is used to mark literal types.
TypeScript
// Type 'hello'
let x = 'hello' as const;
// Type 'readonly [10, 20]'
let y = [10, 20] as const;
// Type '{ readonly text: 'hello' }'
let z = { text: 'hello' } as const;
ArkTS
// Type 'string'.
let x: string = 'hello';
// Type 'number[]'.
let y: number[] = [10, 20];
class Label {
public text: string = '';
}
// Type 'Label'.
let z: Label = {
public text: 'hello',
}
Import Assertions Are Not Supported
Rule: arkts-no-import-assertions
Severity: error
Error code: 10605143
ArkTS does not support import assertions because import is a compile-time feature in ArkTS, not a runtime feature. Therefore, asserting the correctness of imported APIs in runtime does not make sense for the statically typed language. Use the ordinary import syntax instead.
TypeScript
import { obj } from './Something.json' assert { type: 'json' }
ArkTS
// The correctness of importing T will be checked at compile time.
import { Something } from './ExportMod'
Usage of Standard Libraries Is Restricted
Rule: arkts-limited-stdlib
Severity: error
Error code: 10605144
ArkTS does not support certain APIs in the TypeScript and JavaScript standard libraries. Most of these restricted APIs are used to manipulate objects in a dynamic manner, which is not compatible with static typing. The usage of the following APIs is prohibited:
Properties and functions of the global object: eval
Object: proto, defineGetter, defineSetter,
lookupGetter, lookupSetter, assign, create,
defineProperties, defineProperty, freeze,
fromEntries, getOwnPropertyDescriptor, getOwnPropertyDescriptors,
getOwnPropertySymbols, getPrototypeOf,
hasOwnProperty, is, isExtensible, isFrozen,
isPrototypeOf, isSealed, preventExtensions,
propertyIsEnumerable, seal, setPrototypeOf
Reflect: apply, construct, defineProperty, deleteProperty,
getOwnPropertyDescriptor, getPrototypeOf,
isExtensible, preventExtensions,
setPrototypeOf
Proxy: handler.apply(), handler.construct(),
handler.defineProperty(), handler.deleteProperty(), handler.get(),
handler.getOwnPropertyDescriptor(), handler.getPrototypeOf(),
handler.has(), handler.isExtensible(), handler.ownKeys(),
handler.preventExtensions(), handler.set(), handler.setPrototypeOf()
Strict Type Checking Is Enforced
Severity: error
Error code: 10605999
During compilation, the TypeScript strict mode is used to check the following types:
noImplicitReturns,
strictFunctionTypes,
strictNullChecks,
strictPropertyInitialization.
TypeScript
// Compile-time error only when noImplicitReturns is enabled.
function foo(s: string): string {
if (s != '') {
console.info(s);
return s;
} else {
console.info(s);
}
}
let n: number = null; // Compile-time error only when strictNullChecks is enabled.
ArkTS
function foo(s: string): string {
console.info(s);
return s;
}
let n1: number | null = null;
let n2: number = 0;
If you cannot initialize an instance property by declaration or in a constructor when defining a class, you can use the definite assignment assertion operator (!) to clear the strictPropertyInitialization error.
However, the use of the definite assignment assertion operator (!) increases the risk of code errors. Therefore, you must ensure that the instance property has been assigned a value before being used. Otherwise, the runtime exceptions may occur.
In addition, the use of the definite assignment assertion operator (!) requires a runtime type check, resulting in additional runtime overhead. Therefore, use it only when necessary.
It also generates the error warning: arkts-no-definite-assignment at the compile time.
TypeScript
class C {
name: string // Compile-time error only when strictPropertyInitialization is enabled.
age: number // Compile-time error only when strictPropertyInitialization is enabled.
}
let c = new C();
ArkTS
class C {
name: string = ''
age!: number // warning: arkts-no-definite-assignment
initAge(age: number) {
this.age = age;
}
}
let c = new C();
c.initAge(10);
Disabling Type Checking with In-Place Comments Is Not Allowed
Rule: arkts-strict-typing-required
Severity: error
Error code: 10605146
Type checking in ArkTS is not optional. Disabling type checking in-place with special comments is not allowed. In particular, @ts-ignore and @ts-nocheck annotations are not supported.
TypeScript
// @ts-nocheck
// ...
// Some code with type checking disabled.
// ...
let s1: string = null; // No error is reported.
// @ts-ignore
let s2: string = null; // No error is reported.
ArkTS
let s1: string | null = null; // No error is reported. The types are proper.
let s2: string = null; // Compile-time error
TS/JS File Cannot Import Source Code of ETS File
Rule: arkts-no-ts-deps
Severity: error
Error code: 10605147
An .ets file can import source code of an .ets/.ts/.js file, but a .ts/.js file cannot import source code of an .ets file.
TypeScript
// ExportMod.ts
export class C {
// ...
}
// NoTsDeps.ts
import { C } from './ExportMod'
ArkTS
// ExportMod.ets
export class C {
// ...
}
// lib2.ets
import { C } from './ExportMod'
Classes Cannot Be Used as Objects
Rule: arkts-no-classes-as-obj
Severity: warning
Error Code: 10605149
ArkTS does not support using classes as objects (assigning them to objects, etc.). This is because in ArkTS, a class declaration introduces a new type, not a value.
import Statements After Other Statements Are Not Allowed
Rule: arkts-no-misplaced-imports
Severity: error
Error Code: 10605150
In ArkTS, all import statements except dynamic import statements should go before all other statements in the program.
TypeScript
class C {
s: string = ''
n: number = 0
}
import foo from './ExportMod'
ArkTS
import foo from 'module1'
class C {
s: string = ''
n: number = 0
}
import('module2').then(() => {}).catch(() => {}) // Dynamic import
Usage of ESObject Type Is Restricted
Rule: arkts-limited-esobj
Severity: warning
Error Code: 10605151
ArkTS does not allow using ESObject type in some cases. The most part of limitations are put in place in order to prevent spread of dynamic objects (from an .ts/.js file) in the static codebase (from an .ets file).
Before API version 18, the only scenario where it is allowed to use ESObject as type specifier is in local variable declaration. ESObject type variables can only be assigned by objects that can be called across languages, for example, ESObject, any, unknown, and anonymous types. It is prohibited to initialize ESObject typed variable with statically typed value defined in the .ets file. ESObject typed variables can only be used for functions that can be called across languages or assigned to another ESObject typed variable.
Since API version 18, the ESObject type prohibits object literal assignment while supporting: type annotations in dynamic imports, property access (using both . and [] operators), call expressions, and new expressions.
ArkTS
// lib.d.ts
declare function foo(): any;
declare function bar(a: any): number;
// main.ets
let e0: ESObject = foo(); // Before API version 18, compile-time error: 'ESObject' typed variable can only be local; since API version 18, the ESObject type supports explicit type annotation.
function f() {
let e1 = foo(); // Compile-time error: type of e1 is 'any'.
let e2: ESObject = 1; // Before API version 18, compile-time error: Cannot initialize an ESObject with non-dynamic values; since API version 18, the number type is supported.
let e3: ESObject = {}; // Before API version 18, compile-time error: Cannot initialize an ESObject with non-dynamic values; since API version 18, compile-time error: object literal type is not supported.
let e4: ESObject = []; // Before API version 18, compile-time error: Cannot initialize an ESObject with non-dynamic values; since API version 18, the array type is supported.
let e5: ESObject = ''; // Before API version 18, compile-time error: Cannot initialize an ESObject with non-dynamic values; since API version 18, the string type is supported.
e5['prop']; // Before API version 18, compile-time error: Cannot access dynamic properties of 'ESObject'; since API version 18, property access using square brackets is supported.
e5[1]; // Before API version 18, compile-time error: Cannot access dynamic properties of 'ESObject'; since API version 18, property access using square brackets is supported.
e5.prop; // Before API version 18, compile-time error: Cannot access dynamic properties of 'ESObject'; since API version 18, property access using a dot (.) is supported.
let e6: ESObject = foo(); // OK - Explicitly annotated as 'ESObject'.
let e7: ESObject = e6; // OK - Initialize 'ESObject' with 'ESObject'.
bar(e7); // OK - 'ESObject' is passed to a cross-language function.
}