8.0 KiB
8.0 KiB
TypeScript to ArkTS Migration Guide
Complete guide for migrating TypeScript code to ArkTS, covering all language constraints and adaptation rules.
Table of Contents
Overview
ArkTS is based on TypeScript but enforces stricter rules for:
- Performance: Static analysis enables AOT compilation
- Type Safety: Eliminates runtime type errors
- Predictability: Fixed object structures at compile time
Constraints are categorized as:
- Error: Must fix, blocks compilation
- Warning: Should fix, may become errors in future
Constraint Categories
1. Type System Constraints
Prohibited: any and unknown
// ❌ TypeScript
let value: any = getData();
let result: unknown = parse(input);
// ✅ ArkTS
interface Data { id: number; name: string; }
let value: Data = getData();
let result: Data | null = parse(input);
Prohibited: Type assertions to any
// ❌ TypeScript
(obj as any).dynamicProp = value;
// ✅ ArkTS - Define complete interface
interface MyObject {
existingProp: string;
dynamicProp?: number;
}
let obj: MyObject = { existingProp: 'test' };
obj.dynamicProp = value;
2. Variable Declaration
Prohibited: var
// ❌ TypeScript
var count = 0;
var name = "hello";
// ✅ ArkTS
let count = 0;
const name = "hello";
3. Object Structure Constraints
Prohibited: Runtime property modification
class Point {
x: number = 0;
y: number = 0;
}
let p = new Point();
// ❌ All prohibited
p['z'] = 99; // Dynamic property
delete p.x; // Property deletion
Object.assign(p, {z: 1}); // Runtime extension
// ✅ Define all properties upfront
class Point3D {
x: number = 0;
y: number = 0;
z: number = 0;
}
Prohibited: Structural typing (duck typing)
interface Named { name: string; }
// ❌ TypeScript allows structural matching
let obj = { name: "Alice", age: 25 };
let named: Named = obj; // Works in TS, fails in ArkTS
// ✅ ArkTS requires explicit implementation
class Person implements Named {
name: string = "";
age: number = 0;
}
let named: Named = new Person();
4. Private Fields
Prohibited: # private fields
// ❌ TypeScript
class MyClass {
#secret: string = "";
#getValue(): string { return this.#secret; }
}
// ✅ ArkTS
class MyClass {
private secret: string = "";
private getValue(): string { return this.secret; }
}
5. Symbol Properties
Prohibited: Symbol as property key
// ❌ TypeScript
const sym = Symbol('key');
let obj = { [sym]: 'value' };
// ✅ ArkTS
let obj = { key: 'value' };
6. Prohibited Statements
for...in
// ❌ TypeScript
for (let key in obj) {
console.log(obj[key]);
}
// ✅ ArkTS - Use Object.keys with forEach
Object.keys(obj).forEach((key: string) => {
// Access via typed interface
});
// ✅ ArkTS - Use for...of for arrays
let arr: string[] = ['a', 'b', 'c'];
for (let item of arr) {
console.log(item);
}
delete
// ❌ TypeScript
delete obj.property;
// ✅ ArkTS - Use optional properties
interface Config {
name: string;
value?: number; // Optional, can be undefined
}
let config: Config = { name: 'test', value: undefined };
with
// ❌ TypeScript
with (obj) {
console.log(property);
}
// ✅ ArkTS - Use explicit references
console.log(obj.property);
in operator for type checking
// ❌ TypeScript
if ('name' in person) {
console.log(person.name);
}
// ✅ ArkTS - Use instanceof
if (person instanceof Person) {
console.log(person.name);
}
// ✅ ArkTS - Use discriminated unions
interface Person { type: 'person'; name: string; }
interface Animal { type: 'animal'; species: string; }
type Entity = Person | Animal;
function getName(e: Entity): string {
if (e.type === 'person') {
return e.name;
}
return e.species;
}
7. Interface Constraints
Prohibited: Call signatures and construct signatures
// ❌ TypeScript
interface Callable {
(x: number): number;
new (s: string): Object;
}
// ✅ ArkTS - Use classes
class Calculator {
calculate(x: number): number {
return x * 2;
}
}
class Factory {
create(s: string): Object {
return { value: s };
}
}
8. Other Restrictions
| Feature | Status | Alternative |
|---|---|---|
| Comma expressions | Prohibited (except in for) |
Separate statements |
| Computed property names | Limited | String literal keys |
| Spread on non-arrays | Limited | Explicit copying |
eval() |
Prohibited | Avoid |
Function() constructor |
Prohibited | Arrow functions |
| Prototype modification | Prohibited | Class inheritance |
Migration Examples
Example 1: Dynamic Configuration Object
// ❌ TypeScript
let config: any = {};
config.apiUrl = 'https://api.example.com';
config.timeout = 5000;
config.retry = true;
// ✅ ArkTS
interface AppConfig {
apiUrl: string;
timeout: number;
retry: boolean;
}
let config: AppConfig = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retry: true
};
Example 2: Object Iteration
// ❌ TypeScript
interface User { name: string; age: number; }
let user: User = { name: 'John', age: 30 };
for (let key in user) {
console.log(`${key}: ${user[key]}`);
}
// ✅ ArkTS
interface User {
name: string;
age: number;
}
let user: User = { name: 'John', age: 30 };
console.log(`name: ${user.name}`);
console.log(`age: ${user.age}`);
// Or use explicit property list
const props: (keyof User)[] = ['name', 'age'];
for (let prop of props) {
// Handle each known property
}
Example 3: Optional Property Handling
// ❌ TypeScript
let obj: any = { a: 1 };
if (obj.b) {
delete obj.b;
}
obj.c = 3;
// ✅ ArkTS
interface MyObj {
a: number;
b?: number;
c?: number;
}
let obj: MyObj = { a: 1 };
if (obj.b !== undefined) {
obj.b = undefined; // Set to undefined instead of delete
}
obj.c = 3;
Example 4: Type Guards
// ❌ TypeScript
function process(input: unknown) {
if (typeof input === 'string') {
return input.toUpperCase();
}
if ('length' in input) {
return (input as any[]).length;
}
}
// ✅ ArkTS
function processString(input: string): string {
return input.toUpperCase();
}
function processArray(input: string[]): number {
return input.length;
}
// Use union types with type narrowing
type Input = string | string[];
function process(input: Input): string | number {
if (typeof input === 'string') {
return input.toUpperCase();
}
return input.length;
}
Migration Checklist
Phase 1: Enable Strict Mode
- Enable
strict: truein tsconfig.json - Enable
noImplicitAny: true - Enable
strictNullChecks: true - Fix all resulting errors
Phase 2: Remove Prohibited Keywords
- Replace all
varwithlet/const - Remove all
anytype annotations - Remove all
unknowntype annotations - Replace
#private fields withprivate
Phase 3: Fix Object Patterns
- Replace dynamic property access with typed interfaces
- Remove
deletestatements - Remove
for...inloops - Remove
withstatements - Replace
inoperator type checks
Phase 4: Update Interfaces
- Remove call signatures from interfaces
- Remove construct signatures from interfaces
- Replace structural typing with explicit implements
Phase 5: Validate
- Build with ArkTS compiler
- Fix remaining errors
- Test all functionality