久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

從TypeScript到ArkTS的遷移指導(dǎo)【堅(jiān)果派】

 大前端之旅 2023-09-09 發(fā)布于甘肅

從TypeScript到ArkTS的遷移指導(dǎo)

本文通過提供簡潔的約束指導(dǎo)如何將標(biāo)準(zhǔn)的TypeScript代碼重構(gòu)為ArkTS代碼,。盡管ArkTS是基于TypeScript設(shè)計(jì)的,但出于性能考慮,一些TypeScript的特性被限制了。因此,在ArkTS中,所有的TypeScript特性被分成三類,。

  1. 完全支持的特性:原始代碼無需任何修改,。根據(jù)測試,對于已遵循最佳TypeScript實(shí)踐的項(xiàng)目,代碼庫中90%到97%的內(nèi)容可以保持原封不動(dòng)。
  2. 部分支持的特性:需小規(guī)模的代碼重構(gòu),。例如,必須使用關(guān)鍵字let代替var來聲明變量,。
  3. 不支持的特性:需大規(guī)模的代碼重構(gòu)。例如,不支持any類型,所有使用any的代碼都需要引入顯式類型,。

本文將逐一介紹所有部分支持和所有不支持的特性,并提供代碼重構(gòu)的建議,。根據(jù)本文提供的約束進(jìn)行代碼重構(gòu)后代碼仍為有效的TypeScript代碼。對于沒有提到的特性,則說明ArkTS完全支持,。

示例

包含關(guān)鍵字var的原始TypeScript代碼:

function addTen(x: number): number {
    var ten = 10
    return x + ten
}

重構(gòu)后的代碼:

// 重要!重構(gòu)后仍然是有效的TypeScript代碼,。
function addTen(x: number): number {
    let ten = 10
    return x + ten
}

不支持的特性

目前,不支持的特性主要包括:

  • 與降低運(yùn)行時(shí)性能的動(dòng)態(tài)類型相關(guān)的特性。
  • 需要編譯器額外支持從而導(dǎo)致項(xiàng)目構(gòu)建時(shí)間增加的特性,。

根據(jù)開發(fā)者的反饋以及更多實(shí)際場景的數(shù)據(jù),我們將來可能進(jìn)一步縮小不支持特性的范圍,。

概述

本節(jié)羅列了ArkTS不支持或部分支持的TypeScript特性,。完整的列表以及詳細(xì)的代碼示例和重構(gòu)建議,請參考。

強(qiáng)制使用靜態(tài)類型

ArkTS在設(shè)計(jì)之初,就確定了如下目標(biāo):

  • ArkTS代碼需非常容易閱讀和理解,因?yàn)榇a的閱讀頻率高于編寫頻率,。
  • 以最小功耗快速執(zhí)行代碼,這點(diǎn)對于移動(dòng)設(shè)備(ArkTS的目標(biāo)設(shè)備)來說至關(guān)重要,。

靜態(tài)類型是ArkTS最重要的特性之一。使用靜態(tài)類型有助于實(shí)現(xiàn)上述兩個(gè)目標(biāo),。如果程序采用靜態(tài)類型,即所有類型在編譯時(shí)都是已知的,那么開發(fā)者就能夠容易理解代碼中使用了哪些數(shù)據(jù)結(jié)構(gòu),。同時(shí),由于所有類型在程序?qū)嶋H運(yùn)行前都是已知的,編譯器可以提前驗(yàn)證代碼的正確性,從而可以減少運(yùn)行時(shí)的類型檢查,有助于性能提升。

基于上述考慮,ArkTS中禁止使用any類型,。

示例

//
// 不支持:
//

let res : any = some_api_function("hello", "world")

// `res`是什么?錯(cuò)誤代碼的數(shù)字?字符串?對象?
// 該如何處理它?

//
// 支持:
//

class CallResult {
    public succeeded() : boolean { ... }
    public errorMessage() : string { ... }
}

let res : CallResult = some_api_function("hello", "world")
if (!res.succeeded()) {
    console.log("Call failed: " + res.errorMessage())
}

any類型在TypeScript中并不常見,只有大約1%的TypeScript代碼庫使用,。一些代碼檢查工具(例如ESLint)也制定一系列規(guī)則來禁止使用any。因此,雖然禁止any將導(dǎo)致代碼重構(gòu),但重構(gòu)量很小,有助于整體性能提升,因此這個(gè)約束是非常有價(jià)值的,。

禁止在運(yùn)行時(shí)變更對象布局

為實(shí)現(xiàn)最佳性能,ArkTS要求在程序執(zhí)行期間不能更改對象的布局,。換句話說,ArkTS禁止以下行為:

  • 向?qū)ο笾刑砑有碌膶傩曰蚍椒?/li>
  • 從對象中刪除已有的屬性或方法
  • 將任意類型的值賦值給對象屬性

TypeScript編譯器已經(jīng)禁止了許多此類操作。然而,有些操作還是有可能繞過編譯器的,例如,使用ArkTS不支持的as any進(jìn)行轉(zhuǎn)換,。(詳見下面的示例,。)

示例

class Point {
    public x : number = 0
    public y : number = 0

    constructor(x : number, y : number) {
        this.x = x
        this.y = y
    }
}

// 無法從對象中刪除某個(gè)屬性,從而確保所有Point對象都具有屬性x:
let p1 = new Point(1.0, 1.0)
delete p1.x           // 在TypeScript和ArkTS中,都會產(chǎn)生編譯時(shí)錯(cuò)誤
delete (p1 as any).x  // 在TypeScript中不會報(bào)錯(cuò);在ArkTS中會產(chǎn)生編譯時(shí)錯(cuò)誤

// Point類沒有定義命名為z的屬性,在程序運(yùn)行時(shí)也無法添加該屬性:
let p2 = new Point(2.0, 2.0)
p2.z = "Label";         // 在TypeScript和ArkTS中,都會產(chǎn)生編譯時(shí)錯(cuò)誤
(p2 as any).z = "Label" // 在TypeScript中不會報(bào)錯(cuò);在ArkTS中會產(chǎn)生編譯時(shí)錯(cuò)誤

// 類的定義確保了所有Point對象只有屬性x和y,并且無法被添加其他屬性:
let p3 = new Point(3.0, 3.0)
let prop = Symbol();     // 在TypeScript中不會報(bào)錯(cuò);在ArkTS中會產(chǎn)生編譯時(shí)錯(cuò)誤
(p3 as any)[prop] = p3.x // 在TypeScript中不會報(bào)錯(cuò);在ArkTS中會產(chǎn)生編譯時(shí)錯(cuò)誤
p3[prop] = p3.x          // 在TypeScript和ArkTS中,都會產(chǎn)生編譯時(shí)錯(cuò)誤

// 類的定義確保了所有Point對象的屬性x和y都具有number類型,因此,無法將其他類型的值賦值給它們:
let p4 = new Point(4.0, 4.0)
p4.x = "Hello!";         // 在TypeScript和ArkTS中,都會產(chǎn)生編譯時(shí)錯(cuò)誤
(p4 as any).x = "Hello!" // 在TypeScript中不會報(bào)錯(cuò);在ArkTS中會產(chǎn)生編譯時(shí)錯(cuò)誤

// 使用符合類定義的Point對象:
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.log("Distance between p5 and p6: " + distance(p5, p6))

修改對象布局會影響代碼的可讀性以及運(yùn)行時(shí)性能。從開發(fā)者的角度來說,在某處定義類,然后又在其他地方修改實(shí)際的對象布局,很容易引起困惑乃至引入錯(cuò)誤,。此外,這點(diǎn)還需要額外的運(yùn)行時(shí)支持,增加了執(zhí)行開銷,。這一點(diǎn)與靜態(tài)類型的約束也沖突:既然已決定使用顯式類型,為什么還需要添加或刪除屬性呢?

當(dāng)前,只有少數(shù)項(xiàng)目允許在運(yùn)行時(shí)變更對象布局,一些常用的代碼檢查工具也增加了相應(yīng)的限制規(guī)則。這個(gè)約束只會導(dǎo)致少量代碼重構(gòu),但對性能提升會有積極的影響,。

限制運(yùn)算符的語義

為獲得更好的性能并鼓勵(lì)開發(fā)者編寫更清晰的代碼,ArkTS限制了一些運(yùn)算符的語義,。詳細(xì)的語義限制,請參考。

示例

// 一元運(yùn)算符`+`只能作用于數(shù)值類型:
console.log(+42)   // 合法運(yùn)算
console.log(+"42") // 編譯時(shí)錯(cuò)誤

使用額外的語義重載語言運(yùn)算符會增加語言規(guī)范的復(fù)雜度,而且,開發(fā)者還被迫牢記所有可能的例外情況及對應(yīng)的處理規(guī)則,。在某些情況下,產(chǎn)生一些不必要的運(yùn)行時(shí)開銷,。

當(dāng)前只有不到1%的代碼庫使用該特性。因此,盡管限制運(yùn)算符的語義需要重構(gòu)代碼,但重構(gòu)量很小且非常容易操作,并且,通過重構(gòu)能使代碼更清晰,、具備更高性能,。

不支持 structural typing

假設(shè)兩個(gè)不相關(guān)的類TU擁有相同的publicAPI:

class T {
    public name : string = ""

    public greet() : void {
        console.log("Hello, " + this.name)
    }
}

class U {
    public name : string = ""

    public greet() : void {
        console.log("Greetings, " + this.name)
    }
}

我們能把類型為T的值賦給類型為U的變量嗎?

let u : U = new T() // 是否允許?

我們能把類型為T的值傳遞給接受類型為U的參數(shù)的函數(shù)嗎?

function greeter(u : U) {
    console.log("To " + u.name)
    u.greet()
}

let t : T = new T()
greeter(t) // 是否允許?

換句話說,我們將采取下面哪種方法呢:

  • TU沒有繼承關(guān)系或沒有implements相同的接口,但由于它們具有相同的publicAPI,它們“在某種程度上是相等的”,所以上述兩個(gè)問題的答案都是“是”;
  • TU沒有繼承關(guān)系或沒有implements相同的接口,應(yīng)當(dāng)始終被視為完全不同的類型,因此上述兩個(gè)問題的答案都是“否”,。

采用第一種方法的語言支持structural typing,而采用第二種方法的語言則不支持structural typing,。目前TypeScript支持structural typing,而ArkTS不支持。

structural typing是否有助于生成清晰,、易理解的代碼,關(guān)于這一點(diǎn)并沒有定論,。但至少有一點(diǎn)很明確,structural typing不會降低程序的性能(至少在某些時(shí)候)。那為什么ArkTS不支持structural typing呢?

因?yàn)閷tructural typing的支持是一個(gè)重大的特性,需要在語言規(guī)范,、編譯器和運(yùn)行時(shí)進(jìn)行大量的考慮和仔細(xì)的實(shí)現(xiàn),。另外,安全高效的實(shí)現(xiàn)還要考慮到其他方面(靜態(tài)類型、更改對象布局的限制),。鑒于此,當(dāng)前我們還不支持該特性,。根據(jù)實(shí)際場景的需求和反饋,我們后續(xù)會重新加以考慮,。更多案例和建議請參考。

約束說明

對象的屬性名必須是合法的標(biāo)識符

規(guī)則:arkts-identifiers-as-prop-names

級別:錯(cuò)誤

在ArkTS中,對象的屬性名不能為數(shù)字或字符串,。通過屬性名訪問類的屬性,通過數(shù)值索引訪問數(shù)組元素,。

TypeScript

var x = {"name": 1, 2: 3}

console.log(x["name"])
console.log(x[2])

ArkTS

class X {
    public name: number = 0
}
let x: X = {name: 1}
console.log(x.name)

let y = [1, 2, 3]
console.log(y[2])

// 在需要通過非標(biāo)識符(即不同類型的key)獲取數(shù)據(jù)的場景中,使用Map<Object, some_type>:
let z = new Map<Object, number>()
z.set("name", 1)
z.set(2, 2)
console.log(z.get("name"))
console.log(z.get(2))

相關(guān)約束

  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 不支持delete運(yùn)算符
  • 僅允許在表達(dá)式中使用typeof運(yùn)算符
  • 不支持in運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性
  • 限制使用標(biāo)準(zhǔn)庫

不支持Symbol()API

規(guī)則:arkts-no-symbol

級別:錯(cuò)誤

TypeScript中的Symbol()API用于在運(yùn)行時(shí)生成唯一的屬性名稱。由于該API的常見使用場景在靜態(tài)類型語言中沒有意義,因此,ArkTS不支持Symbol()API,。在ArkTS中,對象布局在編譯時(shí)就確定了,且不能在運(yùn)行時(shí)被更改,。

ArkTS也不支持Symbol.iteratorIterable interface。請使用數(shù)組或容器,。

TypeScript

const sym = Symbol()
let o = {
   [sym]: "value"
}

let obj = {
    data: ['a', 'b', 'c'],
    [Symbol.iterator]() {
        const this_ = this
        let index = 0
        return {
            next() {
                return {
                    done: index >= this_.data.length,
                    value: 'name_' + this_.data[index++]
                }
            }
        }
    }
}

for (let t of obj) {
    console.log(t)
}

ArkTS

class SomeClass {
    public someProperty : string = ""
}
let o = new SomeClass()

let arr:string[] = ['a', 'b', 'c']
for (let t of arr) {
    console.log('name_' + t)
}

相關(guān)約束

  • 僅支持屬性名為標(biāo)識符的對象
  • 不支持通過索引訪問字段
  • 不支持delete運(yùn)算符
  • 僅允許在表達(dá)式中使用typeof運(yùn)算符
  • 不支持in運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性
  • 限制使用標(biāo)準(zhǔn)庫

不支持以#開頭的私有字段

規(guī)則:arkts-no-private-identifiers

級別:錯(cuò)誤

ArkTS不支持使用#符號開頭聲明的私有字段,。改用private關(guān)鍵字。

TypeScript

class C {
    #foo: number = 42
}

ArkTS

class C {
    private foo: number = 42
}

類型,、命名空間的命名必須唯一

規(guī)則:arkts-unique-names

級別:錯(cuò)誤

類型(類,、接口、枚舉),、命名空間的命名必須唯一,且與其他名稱(例如:變量名,、函數(shù)名)不同。

TypeScript

let X: string
type X = number[] // 類型的別名與變量同名

ArkTS

let X: string
type T = number[] // 為避免名稱沖突,此處不允許使用X

使用let而非var

規(guī)則:arkts-no-var

級別:錯(cuò)誤

ArkTS不支持 var,請始終使用let代替,。

TypeScript

function f(shouldInitialize: boolean) {
    if (shouldInitialize) {
       var x = 10
    }
    return x
}

console.log(f(true))  // 10
console.log(f(false)) // undefined

let upper_let = 0
{
    var scoped_var = 0
    let scoped_let = 0
    upper_let = 5
}
scoped_var = 5 // 可見
scoped_let = 5 // 編譯時(shí)錯(cuò)誤

ArkTS

function f(shouldInitialize: boolean): Object {
    let x: Object = new Object()
    if (shouldInitialize) {
        x = 10
    }
    return x
}

console.log(f(true))  // 10
console.log(f(false)) // {}

let upper_let = 0
let scoped_var = 0
{
    let scoped_let = 0
    upper_let = 5
}
scoped_var = 5
scoped_let = 5 //編譯時(shí)錯(cuò)誤

使用具體的類型而非anyunknown

規(guī)則:arkts-no-any-unknown

級別:錯(cuò)誤

ArkTS不支持anyunknown類型,。顯式指定具體類型。

TypeScript

let value1 : any
value1 = true
value1 = 42

let value2 : unknown
value2 = true
value2 = 42

ArkTS

let value_b: boolean = true // 或者 let value_b = true
let value_n: number = 42 // 或者 let value_n = 42
let value_o1: Object = true
let value_o2: Object = 42

相關(guān)約束

  • 使用Object[]而非tuple

使用Object[]而非tuple

規(guī)則:arkts-no-tuples

級別:錯(cuò)誤

當(dāng)前ArkTS不支持tuple,??梢允褂?code>Object[]來代替tuple。

TypeScript

var t: [number, string] = [3, "three"]
var n = t[0]
var s = t[1]

ArkTS

let t: Object[] = [3, "three"]
let n = t[0]
let s = t[1]

使用class而非具有call signature的類型

規(guī)則:arkts-no-call-signatures

級別:錯(cuò)誤

ArkTS不支持對象類型中包含call signature,。改用類,。

TypeScript

type DescribableFunction = {
    description: string
    (someArg: number): string // call signature
}

function doSomething(fn: DescribableFunction): void {
    console.log(fn.description + " returned " + fn(6))
}

ArkTS

class DescribableFunction {
    description: string
    public invoke(someArg: number): string {
        return someArg.toString()
    }
    constructor() {
        this.description = "desc"
    }
}

function doSomething(fn: DescribableFunction): void {
    console.log(fn.description + " returned " + fn.invoke(6))
}

doSomething(new DescribableFunction())

相關(guān)約束

  • 使用class而非具有構(gòu)造簽名的類型

使用class而非具有構(gòu)造簽名的類型

規(guī)則:arkts-no-ctor-signatures-type

級別:錯(cuò)誤

ArkTS不支持對象類型中的構(gòu)造簽名。改用類,。

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)
}

相關(guān)約束

  • 使用class而非具有call signature的類型

僅支持一個(gè)靜態(tài)塊

規(guī)則:arkts-no-multiple-static-blocks

級別:錯(cuò)誤

ArkTS不允許類中有多個(gè)靜態(tài)塊,。如果存在多個(gè)靜態(tài)塊語句,請合并到一個(gè)靜態(tài)塊中。

TypeScript

class C {
    static s: string

    static {
        C.s = "aa"
    }
    static {
        C.s = C.s + "bb"
    }
}

ArkTS

class C {
    static s: string

    static {
        C.s = "aa"
        C.s = C.s + "bb"
    }
}

不支持index signature

規(guī)則:arkts-no-indexed-signatures

級別:錯(cuò)誤

ArkTS不允許index signature,。改用數(shù)組,。

TypeScript

// 帶index 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]

使用繼承而非intersection type

規(guī)則:arkts-no-intersection-types

級別:錯(cuò)誤

目前ArkTS不支持intersection type??梢允褂美^承作為替代方案,。

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 {}

不支持this類型

規(guī)則:arkts-no-typing-with-this

級別:錯(cuò)誤

ArkTS不支持this類型。改用顯式具體類型,。

TypeScript

interface ListItem {
    getHead(): this
}

class C {
    n: number = 0

    m(c: this) {
        console.log(c)
    }
}

ArkTS

interface ListItem {
    getHead(): ListItem
}

class C {
    n: number = 0

    m(c: C) {
        console.log(c)
    }
}

不支持條件類型

規(guī)則:arkts-no-conditional-types

級別:錯(cuò)誤

ArkTS不支持條件類型別名,。引入帶顯式約束的新類型,或使用Object重寫邏輯。不支持infer關(guān)鍵字。

TypeScript

type X<T> = T extends number ? T : never

type Y<T> = T extends Array<infer Item> ? Item : never

ArkTS

// 在類型別名中提供顯式約束
type X1<T extends number> = T

// 用Object重寫,這種情況下,類型控制較少,需要更多的類型檢查以確保安全
type X2<T> = Object

// Item必須作為泛型參數(shù)使用,并能正確實(shí)例化
type YI<Item, T extends Array<Item>> = Item

不支持在constructor中聲明字段

規(guī)則:arkts-no-ctor-prop-decls

級別:錯(cuò)誤

ArkTS不支持在constructor中聲明類字段,。在class中聲明這些字段,。

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
    }
}

接口中不支持構(gòu)造簽名

規(guī)則:arkts-no-ctor-signatures-iface

級別:錯(cuò)誤

ArkTS不支持在接口中使用構(gòu)造簽名。改用函數(shù)或者方法,。

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")
}

相關(guān)約束

  • 使用class而非具有構(gòu)造簽名的類型

不支持索引訪問類型

規(guī)則:arkts-no-aliases-by-index

級別:錯(cuò)誤

ArkTS不支持索引訪問類型,。改用類型別名。

TypeScript

type Point = {x: number, y: number}
type N = Point["x"] // 等同于number

ArkTS

class Point {x: number = 0; y: number = 0}
type N = number

不支持通過索引訪問字段

規(guī)則:arkts-no-props-by-index

級別:錯(cuò)誤

ArkTS不支持動(dòng)態(tài)聲明字段,不支持動(dòng)態(tài)訪問字段,。只能訪問已在類中聲明或者繼承可見的字段,訪問其他字段將會造成編譯時(shí)錯(cuò)誤,。
使用點(diǎn)操作符訪問字段,例如(obj.field),不支持索引訪問(obj[field])。
ArkTS支持通過索引訪問TypedArray(例如Int32Array)中的元素,。

TypeScript

class Point {
    x: number = 0
    y: number = 0
}
let p: Point = {x: 1, y: 2}
console.log(p["x"])

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: number = 0
    y: number = 0
}
let p: Point = {x: 1, y: 2}
console.log(p.x)

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.log(person["name"])         // 編譯時(shí)錯(cuò)誤
console.log(person.unknownProperty) // 編譯時(shí)錯(cuò)誤

let arr = new Int32Array(1)
console.log(arr[0])

不支持structural typing

規(guī)則:arkts-no-structural-typing

級別:錯(cuò)誤

ArkTS不支持structural typing,編譯器無法比較兩種類型的publicAPI并決定它們是否相同,。使用其他機(jī)制,例如繼承、接口或類型別名,。

TypeScript

interface I1 {
    f(): string
}

interface I2 { // I2等價(jià)于I1
    f(): string
}

class X {
    n: number = 0
    s: string = ""
}

class Y { // Y等價(jià)于X
    n: number = 0
    s: string = ""
}

let x = new X()
let y = new Y()

console.log("Assign X to Y")
y = x

console.log("Assign Y to X")
x = y

function foo(x: X) {
    console.log(x.n, x.s)
}

// 由于X和Y的API是等價(jià)的,所以X和Y是等價(jià)的
foo(new X())
foo(new Y())

ArkTS

interface I1 {
    f(): string
}

type I2 = I1 // I2是I1的別名

class B {
    n: number = 0
    s: string = ""
}

// D是B的繼承類,構(gòu)建了子類型和父類型的關(guān)系
class D extends B {
    constructor() {
        super()
    }
}

let b = new B()
let d = new D()

console.log("Assign D to B")
b = d // 合法賦值,因?yàn)锽是D的父類

// 將b賦值給d將會引起編譯時(shí)錯(cuò)誤
// d = b

interface Z {
   n: number
   s: string
}

// 類X implements 接口Z,構(gòu)建了X和Y的關(guān)系
class X implements Z {
    n: number = 0
    s: string = ""
}

// 類Y implements 接口Z,構(gòu)建了X和Y的關(guān)系
class Y implements Z {
    n: number = 0
    s: string = ""
}

let x: Z = new X()
let y: Z = new Y()

console.log("Assign X to Y")
y = x // 合法賦值,它們是相同的類型

console.log("Assign Y to X")
x = y // 合法賦值,它們是相同的類型

function foo(c: Z): void {
    console.log(c.n, c.s)
}

// 類X和類Y implement 相同的接口,因此下面的兩個(gè)函數(shù)調(diào)用都是合法的
foo(new X())
foo(new Y())

需要顯式標(biāo)注泛型函數(shù)類型實(shí)參

規(guī)則:arkts-no-inferred-generic-params

級別:錯(cuò)誤

如果可以從傳遞給泛型函數(shù)的參數(shù)中推斷出具體類型,ArkTS允許省略泛型類型實(shí)參,。否則,省略泛型類型實(shí)參會發(fā)生編譯時(shí)錯(cuò)誤。禁止僅基于泛型函數(shù)返回類型推斷泛型類型參數(shù),。

TypeScript

function choose<T>(x: T, y: T): T {
    return Math.random() < 0.5 ? x : y
}

let x = choose(10, 20)   // OK,推斷choose<number>(...)
let y = choose("10", 20) // 編譯時(shí)錯(cuò)誤

function greet<T>(): T {
    return "Hello" as T
}
let z = greet() // T的類型被推斷為“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>(...)
let y = choose("10", 20) // 編譯時(shí)錯(cuò)誤

function greet<T>(): T {
    return "Hello" as T
}
let z = greet<string>()

不支持使用正則字面量

規(guī)則:arkts-no-regexp-literals

級別:錯(cuò)誤

當(dāng)前ArkTS不支持正則字面量,。請使用RegExp()創(chuàng)建正則對象。

TypeScript

let regex: RegExp = /bc*d/

ArkTS

let regex: RegExp = new RegExp("/bc*d/")

需要顯式標(biāo)注對象字面量的類型

規(guī)則:arkts-no-untyped-obj-literals

級別:錯(cuò)誤

在ArkTS中,需要顯式標(biāo)注對象字面量的類型,否則,將發(fā)生編譯時(shí)錯(cuò)誤,。在某些場景下,編譯器可以根據(jù)上下文推斷出字面量的類型,。

在以下上下文中不支持使用字面量初始化類和接口:

  • 初始化具有anyObjectobject類型的任何對象
  • 初始化帶有方法的類或接口
  • 初始化包含自定義含參數(shù)的構(gòu)造函數(shù)的類
  • 初始化帶readonly字段的類

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"}]

class C2 {
    s: string
    constructor(s: string) {
        this.s = "s =" + s
    }
}
let o4: C2 = {s: "foo"}

class C3 {
    readonly n: number = 0
    readonly s: string = ""
}
let o5: C3 = {n: 42, s: "foo"}

abstract class A {}
let o6: A = {}

class C4 {
    n: number = 0
    s: string = ""
    f() {
        console.log("Hello")
    }
}
let o7: C4 = {n: 42, s: "foo", f : () => {}}

class Point {
    x: number = 0
    y: number = 0
}

function id_x_y(o: Point): Point {
    return o
}

// TS支持structural typing,可以推斷p的類型為Point
let p = {x: 5, y: 10}
id_x_y(p)

// 可通過上下文推斷出對象字面量的類型為Point
id_x_y({x: 5, y: 10})

ArkTS

class C1 {
    n: number = 0
    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"}]

class C2 {
    s: string
    constructor(s: string) {
        this.s = "s =" + s
    }
}
let o4 = new C2("foo")

class C3 {
    n: number = 0
    s: string = ""
}
let o5: C3 = {n: 42, s: "foo"}

abstract class A {}
class C extends A {}
let o6: C = {} // 或 let o6: C = new C()

class C4 {
    n: number = 0
    s: string = ""
    f() {
        console.log("Hello")
    }
}
let o7 = new C4()
o7.n = 42
o7.s = "foo"

class Point {
    x: number = 0
    y: number = 0

    // 在字面量初始化之前,使用constructor()創(chuàng)建一個(gè)有效對象,。
    // 由于沒有為Point定義構(gòu)造函數(shù),編譯器將自動(dòng)添加一個(gè)默認(rèn)構(gòu)造函數(shù),。
}

function id_x_y(o: Point): Point {
    return o
}

// 字面量初始化需要顯式定義類型
let p: Point = {x: 5, y: 10}
id_x_y(p)

// id_x_y接受Point類型,字面量初始化生成一個(gè)Point的新實(shí)例
id_x_y({x: 5, y: 10})

相關(guān)約束

  • 對象字面量不能用于類型聲明
  • 數(shù)組字面量必須僅包含可推斷類型的元素

對象字面量不能用于類型聲明

規(guī)則:arkts-no-obj-literals-as-types

級別:錯(cuò)誤

ArkTS不支持使用對象字面量聲明類型,可以使用類或者接口聲明類型。

TypeScript

let o: {x: number, y: number} = {
    x: 2,
    y: 3
}

type S = Set<{x: number, y: number}>

ArkTS

class O {
    x: number = 0
    y: number = 0
}

let o: O = {x: 2, y: 3}

type S = Set<O>

相關(guān)約束

  • 對象字面量必須對應(yīng)某些顯式聲明的類或接口
  • 數(shù)組字面量必須僅包含可推斷類型的元素

數(shù)組字面量必須僅包含可推斷類型的元素

規(guī)則:arkts-no-noninferrable-arr-literals

級別:錯(cuò)誤

本質(zhì)上,ArkTS將數(shù)組字面量的類型推斷為數(shù)組所有元素的聯(lián)合類型,。如果其中任何一個(gè)元素的類型無法根據(jù)上下文推導(dǎo)出來(例如,無類型的對象字面量),則會發(fā)生編譯時(shí)錯(cuò)誤,。

TypeScript

let a = [{n: 1, s: "1"}, {n: 2, s : "2"}]

ArkTS

class C {
    n: number = 0
    s: string = ""
}

let a1 = [{n: 1, s: "1"} as C, {n: 2, s : "2"} as C] // a1的類型為“C[]”
let a2: C[] = [{n: 1, s: "1"}, {n: 2, s : "2"}]      // a2的類型為“C[]”

相關(guān)約束

  • 對象字面量必須對應(yīng)某些顯式聲明的類或接口
  • 對象字面量不能用于類型聲明

使用箭頭函數(shù)而非函數(shù)表達(dá)式

規(guī)則:arkts-no-func-expressions

級別:錯(cuò)誤

ArkTS不支持函數(shù)表達(dá)式。使用箭頭函數(shù),。

TypeScript

let f = function (s: string) {
    console.log(s)
}

ArkTS

let f = (s: string) => {
    console.log(s)
}

使用泛型函數(shù)而非泛型箭頭函數(shù)

規(guī)則:arkts-no-generic-lambdas

級別:錯(cuò)誤

ArkTS不支持泛型箭頭函數(shù),。

TypeScript

let generic_arrow_func = <T extends String> (x: T) => { return x }

generic_arrow_func("string")

ArkTS

function generic_func<T extends String>(x: T): T {
    return x
}

generic_func<String>("string")

不支持使用類表達(dá)式

規(guī)則:arkts-no-class-literals

級別:錯(cuò)誤

ArkTS不支持使用類表達(dá)式。必須顯式聲明一個(gè)類,。

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 Rectangle {
    constructor(height: number, width: number) {
        this.height = height
        this.width = width
    }

    height: number
    width: number
}

const rectangle = new Rectangle(0.0, 0.0)

類不允許被implements

規(guī)則:arkts-implements-only-iface

級別:錯(cuò)誤

ArkTS不允許類被implements,只有接口可以被implements,。

TypeScript

class C {
  foo() {}
}

class C1 implements C {
  foo() {}
}

ArkTS

interface C {
  foo(): void
}

class C1 implements C {
  foo() {}
}

不支持修改對象的方法

規(guī)則:arkts-no-method-reassignment

級別:錯(cuò)誤

ArkTS不支持修改對象的方法。在靜態(tài)語言中,對象的布局是確定的,。一個(gè)類的所有對象實(shí)例享有同一個(gè)方法,。
如果需要為某個(gè)特定的對象增加方法,可以封裝函數(shù)或者使用繼承的機(jī)制,。

TypeScript

class C {
    foo() {
        console.log("foo")
    }
}

function bar() {
    console.log("bar")
}

let c1 = new C()
let c2 = new C()
c2.foo = bar

c1.foo() // foo
c2.foo() // bar

ArkTS

class C {
    foo() {
        console.log("foo")
    }
}

class Derived extends C {
    foo() {
        console.log("Extra")
        super.foo()
    }
}

function bar() {
    console.log("bar")
}

let c1 = new C()
let c2 = new C()
c1.foo() // foo
c2.foo() // foo

let c3 = new Derived()
c3.foo() // Extra foo

類型轉(zhuǎn)換僅支持as T語法

規(guī)則:arkts-as-casts

級別:錯(cuò)誤

在ArkTS中,as關(guān)鍵字是類型轉(zhuǎn)換的唯一語法,。錯(cuò)誤的類型轉(zhuǎn)換會導(dǎo)致編譯時(shí)錯(cuò)誤或者運(yùn)行時(shí)拋出ClassCastException異常。不支持使用<type>語法進(jìn)行類型轉(zhuǎn)換。

當(dāng)需要將primitive類型(如numberboolean)轉(zhuǎn)換成引用類型時(shí),請使用new表達(dá)式,。

TypeScript

class Shape {}
class Circle extends Shape {x: number = 5}
class Square extends Shape {y: string = "a"}

function createShape(): Shape {
    return new Circle()
}

let c1 = <Circle> createShape()

let c2 = createShape() as Circle

// 如果轉(zhuǎn)換錯(cuò)誤,不會產(chǎn)生編譯時(shí)或運(yùn)行時(shí)報(bào)錯(cuò)
let c3 = createShape() as Square
console.log(c3.y) // undefined

// 在TS中,由于`as`關(guān)鍵字不會在運(yùn)行時(shí)生效,所以`instanceof`的左操作數(shù)不會在運(yùn)行時(shí)被裝箱成引用類型
let e1 = (5.0 as Number) instanceof Number // false

// 創(chuàng)建Number對象,獲得預(yù)期結(jié)果:
let e2 = (new Number(5.0)) instanceof Number // true

ArkTS

class Shape {}
class Circle extends Shape {x: number = 5}
class Square extends Shape {y: string = "a"}

function createShape(): Shape {
    return new Circle()
}

let c2 = createShape() as Circle

// 運(yùn)行時(shí)拋出ClassCastException異常:
let c3 = createShape() as Square

// 創(chuàng)建Number對象,獲得預(yù)期結(jié)果:
let e2 = (new Number(5.0)) instanceof Number // true

不支持JSX表達(dá)式

規(guī)則:arkts-no-jsx

級別:錯(cuò)誤

不支持使用JSX,。

一元運(yùn)算符+-~僅適用于數(shù)值類型

規(guī)則:arkts-no-polymorphic-unops

級別:錯(cuò)誤

ArkTS僅允許一元運(yùn)算符用于數(shù)值類型,否則會發(fā)生編譯時(shí)錯(cuò)誤,。與TypeScript不同,ArkTS不支持隱式將字符串轉(zhuǎn)換成數(shù)值,必須進(jìn)行顯式轉(zhuǎn)換,。

TypeScript

let a = +5        // 5(number類型)
let b = +"5"      // 5(number類型)
let c = -5        // -5(number類型)
let d = -"5"      // -5(number類型)
let e = ~5        // -6(number類型)
let f = ~"5"      // -6(number類型)
let g = +"string" // NaN(number類型)

function returnTen(): string {
    return "-10"
}

function returnString(): string {
    return "string"
}

let x = +returnTen()    // -10(number類型)
let y = +returnString() // NaN

ArkTS

let a = +5        // 5(number類型)
let b = +"5"      // 編譯時(shí)錯(cuò)誤
let c = -5        // -5(number類型)
let d = -"5"      // 編譯時(shí)錯(cuò)誤
let e = ~5        // -6(number類型)
let f = ~"5"      // 編譯時(shí)錯(cuò)誤
let g = +"string" // 編譯時(shí)錯(cuò)誤

function returnTen(): string {
    return "-10"
}

function returnString(): string {
    return "string"
}

let x = +returnTen()    // 編譯時(shí)錯(cuò)誤
let y = +returnString() // 編譯時(shí)錯(cuò)誤

不支持delete運(yùn)算符

規(guī)則:arkts-no-delete

級別:錯(cuò)誤

ArkTS中,對象布局在編譯時(shí)就確定了,且不能在運(yùn)行時(shí)被更改。因此,刪除屬性的操作沒有意義,。

TypeScript

class Point {
    x?: number = 0.0
    y?: number = 0.0
}

let p = new Point()
delete p.y

ArkTS

// 可以聲明一個(gè)可空類型并使用null作為缺省值
class Point {
    x: number | null = 0
    y: number | null = 0
}

let p = new Point()
p.y = null

相關(guān)約束

  • 對象的屬性名必須是合法的標(biāo)識符
  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 僅允許在表達(dá)式中使用typeof運(yùn)算符
  • 不支持in運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性

僅允許在表達(dá)式中使用typeof運(yùn)算符

規(guī)則:arkts-no-type-query

級別:錯(cuò)誤

ArkTS僅支持在表達(dá)式中使用typeof運(yùn)算符,。不允許使用typeof作為類型。

TypeScript

let n1 = 42
let s1 = "foo"
console.log(typeof n1) // "number"
console.log(typeof s1) // "string"
let n2: typeof n1
let s2: typeof s1

ArkTS

let n1 = 42
let s1 = "foo"
console.log(typeof n1) // "number"
console.log(typeof s1) // "string"
let n2: number
let s2: string

相關(guān)約束

  • 對象的屬性名必須是合法的標(biāo)識符
  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 不支持delete運(yùn)算符
  • 不支持in運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性
  • 限制使用標(biāo)準(zhǔn)庫

部分支持instanceof運(yùn)算符

規(guī)則:arkts-instanceof-ref-types

級別:錯(cuò)誤

在TypeScript中,instanceof運(yùn)算符的左操作數(shù)的類型必須為any類型,、對象類型,或者它是類型參數(shù),否則結(jié)果為false,。在ArkTS中,instanceof運(yùn)算符的左操作數(shù)的類型必須為引用類型,否則會發(fā)生編譯時(shí)錯(cuò)誤。此外,在ArkTS中,instanceof運(yùn)算符的左操作數(shù)不能是類型,。

TypeScript

class X {
    // ...
}

let a = (new X()) instanceof Object // true
let b = (new X()) instanceof X      // true
let c = X instanceof Object         // true, 左操作數(shù)是一個(gè)類型
let d = X instanceof X              // false, 左操作數(shù)是一個(gè)類型

ArkTS

class X {
    // ...
}

let a = (new X()) instanceof Object // true
let b = (new X()) instanceof X      // true
let c = X instanceof Object         // 編譯時(shí)錯(cuò)誤, 左操作數(shù)是一個(gè)類型
let d = X instanceof X              // 編譯時(shí)錯(cuò)誤, 左操作數(shù)是一個(gè)類型

不支持in運(yùn)算符

規(guī)則:arkts-no-in

級別:錯(cuò)誤

由于在ArkTS中,對象布局在編譯時(shí)是已知的并且在運(yùn)行時(shí)無法修改,因此,不支持in運(yùn)算符,。如果仍需檢查某些類成員是否存在,使用instanceof代替。

TypeScript

class Person {
    name: string = ""
}
let p = new Person()

let b = "name" in p // true

ArkTS

class Person {
    name: string = ""
}
let p = new Person()

let b = p instanceof Person // true,且屬性name一定存在

相關(guān)約束

  • 對象的屬性名必須是合法的標(biāo)識符
  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 不支持delete運(yùn)算符
  • 僅允許在表達(dá)式中使用typeof運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性
  • 限制使用標(biāo)準(zhǔn)庫

不支持解構(gòu)賦值

規(guī)則:arkts-no-destruct-assignment

級別:錯(cuò)誤

ArkTS不支持解構(gòu)賦值,??墒褂闷渌娲椒?#xff0c;例如,使用臨時(shí)變量。

TypeScript

let [one, two] = [1, 2]; // 此處需要分號
[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])
}

逗號運(yùn)算符,僅用在for循環(huán)語句中

規(guī)則:arkts-no-comma-outside-loops

級別:錯(cuò)誤

為了方便理解執(zhí)行順序,在ArkTS中,逗號運(yùn)算符,僅適用于for循環(huán)語句中,。

TypeScript

for (let i = 0, j = 0; i < 10; ++i, j += 2) {
    console.log(i)
    console.log(j)
}

let x = 0
x = (++x, x++) // 1

ArkTS

for (let i = 0, j = 0; i < 10; ++i, j += 2) {
    console.log(i)
    console.log(j)
}

// 通過語句表示執(zhí)行順序,而非逗號運(yùn)算符
let x = 0
++x
x = x++

不支持解構(gòu)變量聲明

規(guī)則:arkts-no-destruct-decls

級別:錯(cuò)誤

ArkTS不支持解構(gòu)變量聲明,。它是一個(gè)依賴于結(jié)構(gòu)兼容性的動(dòng)態(tài)特性并且解構(gòu)聲明中的名稱必須和被解構(gòu)對象中的屬性名稱一致。

TypeScript

class Point {
    x: number = 0.0
    y: number = 0.0
}

function returnZeroPoint(): Point {
    return new Point()
}

let {x, y} = returnZeroPoint()

ArkTS

class Point {
    x: number = 0.0
    y: number = 0.0
}

function returnZeroPoint(): Point {
    return new Point()
}

// 創(chuàng)建一個(gè)局部變量來處理每個(gè)字段:
let zp = returnZeroPoint()
let x = zp.x
let y = zp.y

不支持在catch語句標(biāo)注類型

規(guī)則:arkts-no-types-in-catch

級別:錯(cuò)誤

在TypeScript的catch語句中,只能標(biāo)注anyunknown類型,。由于ArkTS不支持這些類型,應(yīng)省略類型標(biāo)注,。

TypeScript

try {
    // 一些代碼
}
catch (a: unknown) {
    // 處理異常
}

ArkTS

try {
    // 一些代碼
}
catch (a) {
    // 處理異常
}

相關(guān)約束

  • 限制throw語句中表達(dá)式的類型

不支持for .. in

規(guī)則:arkts-no-for-in

級別:錯(cuò)誤

由于在ArkTS中,對象布局在編譯時(shí)是確定的、并且不能在運(yùn)行時(shí)被改變,所以不支持使用for .. in迭代一個(gè)對象的屬性,。對于數(shù)組來說,可以使用常規(guī)的for循環(huán),。

TypeScript

let a: number[] = [1.0, 2.0, 3.0]
for (let i in a) {
    console.log(a[i])
}

ArkTS

let a: number[] = [1.0, 2.0, 3.0]
for (let i = 0; i < a.length; ++i) {
    console.log(a[i])
}

相關(guān)約束

  • for-of僅適用于數(shù)組和字符串

for-of僅適用于數(shù)組和字符串

規(guī)則:arkts-for-of-str-arr

級別:錯(cuò)誤

ArkTS支持通過for .. of迭代數(shù)組、字符串和TypedArray(例如Int32Array),但不支持迭代對象,。

TypeScript

let a: Set<number> = new Set([1, 2, 3])
for (let s of a) {
    console.log(s)
}

ArkTS

let a: Set<number> = new Set([1, 2, 3])
let numbers = Array.from(a.values())
for (let n of numbers) {
    console.log(n)
}

相關(guān)約束

  • 不支持for … in

不支持映射類型

規(guī)則:arkts-no-mapped-types

級別:錯(cuò)誤

ArkTS不支持映射類型,。使用其他語法來表示相同的語義。

TypeScript

type OptionsFlags<Type> = {
    [Property in keyof Type]: boolean
}

ArkTS

class C {
    n: number = 0
    s: string = ""
}

class CFlags {
    n: boolean = false
    s: boolean = false
}

相關(guān)約束

  • 不支持keyof運(yùn)算符

不支持with語句

規(guī)則:arkts-no-with

級別:錯(cuò)誤

ArkTS不支持with語句,。使用其他語法來表示相同的語義,。

TypeScript

with (Math) { // 編譯時(shí)錯(cuò)誤, 但是仍能生成JavaScript代碼
    let r: number = 42
    console.log("Area: ", PI * r * r)
}

ArkTS

let r: number = 42
console.log("Area: ", Math.PI * r * r)

限制throw語句中表達(dá)式的類型

規(guī)則:arkts-limited-throw

級別:錯(cuò)誤

ArkTS只支持拋出Error類或其派生類的實(shí)例。禁止拋出其他類型(例如numberstring)的數(shù)據(jù),。

TypeScript

throw 4
throw ""
throw new Error()

ArkTS

throw new Error()

限制省略函數(shù)返回類型標(biāo)注

規(guī)則:arkts-no-implicit-return-types

級別:錯(cuò)誤

ArkTS在部分場景中支持對函數(shù)返回類型進(jìn)行推斷,。當(dāng)return語句中的表達(dá)式是對某個(gè)函數(shù)或方法進(jìn)行調(diào)用,且該函數(shù)或方法的返回類型沒有被顯著標(biāo)注時(shí),會出現(xiàn)編譯時(shí)錯(cuò)誤。在這種情況下,請標(biāo)注函數(shù)返回類型,。

TypeScript

// 只有在開啟noImplicitAny選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
function f(x: number) {
    if (x <= 0) {
        return x
    }
    return g(x)
}

// 只有在開啟noImplicitAny選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
function g(x: number) {
    return f(x - 1)
}

function doOperation(x: number, y: number) {
    return x + y
}

console.log(f(10))
console.log(doOperation(2, 3))

ArkTS

// 需標(biāo)注返回類型:
function f(x: number) : number {
    if (x <= 0) {
        return x
    }
    return g(x)
}

// 可以省略返回類型,返回類型可以從f的類型標(biāo)注推導(dǎo)得到
function g(x: number) : number {
    return f(x - 1)
}

// 可以省略返回類型
function doOperation(x: number, y: number) {
    return x + y
}

console.log(f(10))
console.log(doOperation(2, 3))

不支持參數(shù)解構(gòu)的函數(shù)聲明

規(guī)則:arkts-no-destruct-params

級別:錯(cuò)誤

ArkTS要求實(shí)參必須直接傳遞給函數(shù),且必須指定到形參,。

TypeScript

function drawText({ text = "", location: [x, y] = [0, 0], bold = false }) {
    console.log(text)
    console.log(x)
    console.log(y)
    console.log(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]
    console.log(text)
    console.log(x)
    console.log(y)
    console.log(bold)
}

function main() {
    drawText("Hello, world!", [100, 50], true)
}

不支持在函數(shù)內(nèi)聲明函數(shù)

規(guī)則:arkts-no-nested-funcs

級別:錯(cuò)誤

ArkTS不支持在函數(shù)內(nèi)聲明函數(shù),。改用lambda函數(shù)。

TypeScript

function addNum(a: number, b: number): void {

    // 函數(shù)內(nèi)聲明函數(shù):
    function logToConsole(message: String): void {
        console.log(message)
    }

    let result = a + b

    // 調(diào)用函數(shù):
    logToConsole("result is " + result)
}

ArkTS

function addNum(a: number, b: number): void {
    // 使用lambda函數(shù)代替聲明函數(shù):
    let logToConsole: (message: string) => void = (message: string): void => {
        console.log(message)
    }

    let result = a + b

    logToConsole("result is " + result)
}

不支持在函數(shù)和類的靜態(tài)方法中使用this

規(guī)則:arkts-no-standalone-this

級別:錯(cuò)誤

ArkTS不支持在函數(shù)和類的靜態(tài)方法中使用this,。只能在類的實(shí)例方法中使用this,。

TypeScript

function foo(i: number) {
    this.count = i // 只有在開啟noImplicitThis選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
}

class A {
    count: number = 1
    m = foo
}

let a = new A()
console.log(a.count) // 打印“1”
a.m(2)
console.log(a.count) // 打印“2”

ArkTS

class A {
    count: number = 1
    m(i: number): void {
        this.count = i
    }
}

function main(): void {
    let a = new A()
    console.log(a.count)  // 打印"1"
    a.m(2)
    console.log(a.count)  // 打印"2"
}

相關(guān)約束

  • 不支持Function.apply、Function.bind以及Function.call

不支持生成器函數(shù)

規(guī)則:arkts-no-generators

級別:錯(cuò)誤

目前ArkTS不支持生成器函數(shù),。使用asyncawait機(jī)制進(jìn)行并行任務(wù)處理,。

TypeScript

function* counter(start: number, end: number) {
    for (let i = start; i <= end; i++) {
        yield i
    }
}

for (let num of counter(1, 5)) {
    console.log(num)
}

ArkTS

async function complexNumberProcessing(n : number) : Promise<number> {
    //一些代碼邏輯
    return n
}

async function foo() {
    for (let i = 1; i <= 5; i++) {
        console.log(await complexNumberProcessing(i))
    }
}

foo()

使用instanceofas進(jìn)行類型保護(hù)

規(guī)則:arkts-no-is

級別:錯(cuò)誤

ArkTS不支持is運(yùn)算符,必須用instanceof運(yùn)算符替代。在使用之前,必須使用as運(yùn)算符將對象轉(zhuǎn)換為需要的類型,。

TypeScript

class Foo {
    foo: number = 0
    common: string = ""
}

class Bar {
    bar: number = 0
    common: string = ""
}

function isFoo(arg: any): arg is Foo {
    return arg.foo !== undefined
}

function doStuff(arg: Foo | Bar) {
    if (isFoo(arg)) {
        console.log(arg.foo)    // OK
        console.log(arg.bar)    // 編譯時(shí)錯(cuò)誤
    } else {
        console.log(arg.foo)    // 編譯時(shí)錯(cuò)誤
        console.log(arg.bar)    // OK
    }
}

doStuff({ foo: 123, common: '123' })
doStuff({ bar: 123, common: '123' })

ArkTS

class Foo {
    foo: number = 0
    common: string = ""
}

class Bar {
    bar: number = 0
    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.log(fooArg.foo)     // OK
        console.log(arg.bar)        // 編譯時(shí)錯(cuò)誤
    } else {
        let barArg = arg as Bar
        console.log(arg.foo)        // 編譯時(shí)錯(cuò)誤
        console.log(barArg.bar)     // OK
    }
}

function main(): void {
    doStuff(new Foo())
    doStuff(new Bar())
}

不支持keyof運(yùn)算符

規(guī)則:arkts-no-keyof

級別:錯(cuò)誤

在ArkTS中,由于對象布局在編譯時(shí)就確定了,且不能在運(yùn)行時(shí)被更改,因此,不支持使用keyof運(yùn)算符,。直接訪問對象的屬性。

TypeScript

class Point {
    x: number = 1
    y: number = 2
}

type PointKeys = keyof Point  // PointKeys表示Point屬性名稱組成的聯(lián)合類型

function getPropertyValue(obj: Point, key: PointKeys) {
    return obj[key]
}

let obj = new Point()
console.log(getPropertyValue(obj, "x"))  // 打印"1"
console.log(getPropertyValue(obj, "y"))  // 打印"2"

ArkTS

class Point {
    x: number = 1
    y: number = 2
}

function getPropertyValue(obj: Point, key: string): number {
    if (key == "x") {
        return obj.x
    }
    if (key == "y") {
        return obj.y
    }
    throw new Error()  // 處理沒有該屬性的分支
    return 0
}

function main(): void {
    let obj = new Point()
    console.log(getPropertyValue(obj, "x"))  // 打印"1"
    console.log(getPropertyValue(obj, "y"))  // 打印"2"
}

展開運(yùn)算符僅支持函數(shù)剩余參數(shù)為數(shù)組類型

規(guī)則:arkts-no-spread

級別:錯(cuò)誤

展開運(yùn)算符唯一支持的場景是函數(shù)剩余參數(shù)為數(shù)組類型,包括TypedArray(例如Int32Array),。

TypeScript

function foo(x : number, y : number, z : number) {
    console.log(x, y, z)
}

let args : [number, number, number] = [0, 1, 2]
foo(...args)

let list1 = [1, 2]
let list2 = [...list1, 3, 4]

let point2d = {x: 1, y: 2}
let point3d = {...point2d, z: 3}

ArkTS

function sum_numbers(...numbers: number[]): number {
    let res = 0
    for (let n of numbers)
        res += n
    return res
}
console.log(sum_numbers(1, 2, 3))

function log_numbers(x : number, y : number, z : number) {
    console.log(x, y, z)
}

let numbers: number[] = [1, 2, 3]
log_numbers(numbers[0], numbers[1], numbers[2])

let list1 : number[] = [1, 2]
let list2 : number[] = [list1[0], list1[1], 3, 4]

class Point2D {
    x: number = 0; y: number = 0
}

class Point3D {
    x: number = 0; y: number = 0; 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)
console.log(p3d.x, p3d.y, p3d.z)

接口不能繼承具有相同屬性的兩個(gè)接口

規(guī)則:arkts-no-extend-same-prop

級別:錯(cuò)誤

在TypeScript中,如果一個(gè)接口繼承了具有相同方法的兩個(gè)接口,則該接口必須使用聯(lián)合類型來聲明該方法,。在ArkTS中,由于一個(gè)接口中不能包含兩個(gè)無法區(qū)分的方法(例如兩個(gè)參數(shù)列表相同但返回類型不同的方法),因此,接口不能繼承具有相同屬性的兩個(gè)接口。

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 move_status : MoveStatus
    private shake_status : ShakeStatus

    constructor() {
        this.move_status = new MoveStatus()
        this.shake_status = new ShakeStatus()
    }

    public getMoveStatus() : MoveStatus {
        return this.move_status
    }

    public getShakeStatus() : ShakeStatus {
        return this.shake_status
    }

    public getStatus(): MoveAndShakeStatus {
        return {
            speed: this.move_status.speed,
            frequency: this.shake_status.frequency
        }
    }
}

不支持聲明合并

規(guī)則:arkts-no-decl-merging

級別:錯(cuò)誤

ArkTS不支持類,、接口的聲明合并,。

TypeScript

interface Document {
    createElement(tagName: any): Element
}

interface Document {
    createElement(tagName: string): HTMLElement
}

interface Document {
    createElement(tagName: number): HTMLDivElement
    createElement(tagName: boolean): HTMLSpanElement
    createElement(tagName: string, value: number): HTMLCanvasElement
}

ArkTS

interface Document {
    createElement(tagName: number): HTMLDivElement
    createElement(tagName: boolean): HTMLSpanElement
    createElement(tagName: string, value: number): HTMLCanvasElement
    createElement(tagName: string): HTMLElement
    createElement(tagName: Object): Element
}

接口不能繼承類

規(guī)則:arkts-extends-only-class

級別:錯(cuò)誤

ArkTS不支持接口繼承類。接口只能繼承接口,。

TypeScript

class Control {
    state: number = 0
}

interface SelectableControl extends Control {
    select(): void
}

ArkTS

interface Control {
    state: number
}

interface SelectableControl extends Control {
    select(): void
}

禁止運(yùn)行時(shí)檢查對象屬性

規(guī)則:arkts-no-prop-existence-check

級別:錯(cuò)誤

ArkTS中,對象布局在編譯時(shí)就確定了,且不能在運(yùn)行時(shí)被更改,。禁止運(yùn)行時(shí)檢查對象屬性。使用as運(yùn)算符進(jìn)行類型轉(zhuǎn)換以訪問相應(yīng)的屬性和方法,。訪問對象中不存在的屬性將導(dǎo)致編譯時(shí)錯(cuò)誤,。

TypeScript

class A {
    foo() {}
    bar() {}
}

function getSomeObject() {
    return new A()
}

let obj: any = getSomeObject()
if (obj && obj.foo && obj.bar) {
    console.log("Yes")  // 此示例中將打印 "Yes"
} else {
    console.log("No")
}

ArkTS

class A {
    foo(): void {}
    bar(): void {}
}

function getSomeObject(): A {
    return new A()
}

function main(): void {
    let tmp: Object = getSomeObject()
    let obj: A = tmp as A
    obj.foo()       // OK
    obj.bar()       // OK
    obj.some_foo()  // 編譯時(shí)錯(cuò)誤:方法some_foo不存在于此類型上
}

相關(guān)約束

  • 對象的屬性名必須是合法的標(biāo)識符
  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 不支持delete運(yùn)算符
  • 僅允許運(yùn)算符typeof在表達(dá)式上下文中使用
  • 不支持in運(yùn)算符
  • 限制使用標(biāo)準(zhǔn)庫

不支持構(gòu)造函數(shù)類型

規(guī)則:arkts-no-ctor-signatures-funcs

級別:錯(cuò)誤

ArkTS不支持使用構(gòu)造函數(shù)類型。改用lambda函數(shù),。

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 Impersonizer: PersonCtor = (n: string, a: number): Person => {
    return new Person(n, a)
}

const person = createPerson(Impersonizer, "John", 30)

只能使用類型相同的編譯時(shí)表達(dá)式初始化枚舉成員

規(guī)則:arkts-no-enum-mixed-types

級別:錯(cuò)誤

ArkTS不支持使用在運(yùn)行期間才能計(jì)算的表達(dá)式來初始化枚舉成員,。此外,枚舉中所有顯式初始化的成員必須具有相同的類型。

TypeScript

enum E1 {
    A = 0xa,
    B = 0xb,
    C = Math.random(),
    D = 0xd,
    E // 推斷出0xe
}

enum E2 {
    A = 0xa,
    B = "0xb",
    C = 0xc,
    D = "0xd"
}

ArkTS

enum E1 {
    A = 0xa,
    B = 0xb,
    C = 0xc,
    D = 0xd,
    E // 推斷出0xe
}

enum E2 {
    A = "0xa",
    B = "0xb",
    C = "0xc",
    D = "0xd"
}

不支持enum聲明合并

規(guī)則:arkts-no-enum-merging

級別:錯(cuò)誤

ArkTS不支持enum聲明合并,。

TypeScript

enum Color {
    RED,
    GREEN
}
enum Color {
    YELLOW = 2
}
enum Color {
    BLACK = 3,
    BLUE
}

ArkTS

enum Color {
    RED,
    GREEN,
    YELLOW,
    BLACK,
    BLUE
}

命名空間不能被用作對象

規(guī)則:arkts-no-ns-as-obj

級別:錯(cuò)誤

ArkTS不支持將命名空間用作對象,。可以使用類或模塊,。

TypeScript

namespace MyNamespace {
    export let x: number
}

let m = MyNamespace
m.x = 2

ArkTS

namespace MyNamespace {
    export let x: number
}

MyNamespace.x = 2

不支持命名空間中的非聲明語句

規(guī)則:arkts-no-ns-statements

級別:錯(cuò)誤

ArkTS不支持命名空間中的非聲明語句,。可以將非聲明語句寫在函數(shù)中,。

TypeScript

namespace A {
    export let x: number
    x = 1
}

ArkTS

namespace A {
    export let x: number

    export function init() {
      x = 1
    }
}

// 調(diào)用初始化函數(shù)來執(zhí)行:
A.init()

不支持import type

規(guī)則:arkts-no-special-imports

級別:錯(cuò)誤

ArkTS不支持import type,。改為import

TypeScript

// 通用導(dǎo)入語法
import { APIResponseType } from "api"

// 導(dǎo)入類型
import type { APIResponseType } from "api"

ArkTS

import { APIResponseType } from "api"

相關(guān)約束

  • 不支持僅為副作用而導(dǎo)入一個(gè)模塊
  • 不支持import default as …
  • 不支持require和import賦值表達(dá)式

不支持僅為副作用而導(dǎo)入一個(gè)模塊

規(guī)則:arkts-no-side-effects-imports

級別:錯(cuò)誤

ArkTS不支持window等全局變量,避免模塊導(dǎo)入時(shí)產(chǎn)生副作用,??梢酝ㄟ^*語法獲取所有導(dǎo)出的變量。

TypeScript

// === “path/to/module.ts”中的模塊
export const EXAMPLE_VALUE = 42

// 設(shè)置全局變量
window.MY_GLOBAL_VAR = "Hello, world!"

//==== 使用此模塊:
import "path/to/module"

ArkTS

import * as ns from "path/to/module"

不支持import default as ...

規(guī)則:arkts-no-import-default-as

級別:錯(cuò)誤

ArkTS不支持import default as ...語法,。使用顯式的import ... from ...語法,。

TypeScript

import { default as d } from "mod"

ArkTS

import d from "mod"

不支持requireimport賦值表達(dá)式

規(guī)則:arkts-no-require

級別:錯(cuò)誤

ArkTS不支持通過require導(dǎo)入,也不支持import賦值表達(dá)式,。改用import

TypeScript

import m = require("mod")

ArkTS

import * as m from "mod"

相關(guān)約束

  • 不支持export = …語法

部分支持重導(dǎo)出

規(guī)則:arkts-limited-reexport

級別:錯(cuò)誤

ArkTS支持命名重導(dǎo)出和重命名重導(dǎo)出,。支持export * ...的語法,不支持export * as ...的語法,。

TypeScript

// module1
export class Class1 {
    // ...
}
export class Class2 {
    // ...
}

// module2
export * as utilities from "module1"

// consumer模塊
import { utilities } from "module2"

const myInstance = new MyClass()

ArkTS

// module1
export class Class1 {
    // ...
}
export class Class2 {
    // ...
}

// module2
export { Class1 } from "module1"
export { C2 as Class2 } from "module1"

// 支持以下語法
// export * from "module1"

// consumer模塊
import { Class1, Class2 } from "module2"

const myInstance = new MyClass()

相關(guān)約束

  • 不支持export = …語法

不支持export = ...語法

規(guī)則:arkts-no-export-assignment

級別:錯(cuò)誤

ArkTS不支持export = ...語法,。改用常規(guī)的exportimport,。

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.origin

ArkTS

// module1
export class Point {
    constructor(x: number, y: number) {}
    static origin = new Point(0, 0)
}

// module2
import * as Pt from "module1"

let p = Pt.origin

相關(guān)約束

  • 不支持require和import賦值表達(dá)式
  • 部分支持重導(dǎo)出

不支持export type

規(guī)則:arkts-no-special-exports

級別:錯(cuò)誤

ArkTS不支持export type。改用export,。

TypeScript

// 顯式導(dǎo)出class:
export class Class1 {
    // ...
}

// 聲明一個(gè)類,之后通過`export type`導(dǎo)出
class Class2 {
    // ...
}

// 不支持
export type { Class2 }

ArkTS

// 顯式導(dǎo)出class:
export class Class1 {
    // ...
}

// 顯式導(dǎo)出class:
export class Class2 {
    // ...
}

不支持ambient module聲明

規(guī)則:arkts-no-ambient-decls

級別:錯(cuò)誤

ArkTS不支持ambient module聲明,因?yàn)锳rkTS本身有與JavaScript交互的機(jī)制,。

TypeScript

declare module "someModule" {
    export function normalize(s : string) : string;
}

ArkTS

// 從原始模塊中導(dǎo)入需要的內(nèi)容
import { normalize } from "someModule"

相關(guān)約束

  • 不支持在模塊名中使用通配符
  • 模塊標(biāo)識符中不允許使用.js擴(kuò)展名

不支持在模塊名中使用通配符

規(guī)則:arkts-no-module-wildcards

級別:錯(cuò)誤

由于在ArkTS中,導(dǎo)入是編譯時(shí)而非運(yùn)行時(shí)行為,因此,不支持在模塊名中使用通配符。

TypeScript

// 聲明
declare module "*!text" {
    const content: string
    export default content
}

import fileContent from "some.txt!text"

ArkTS

// 聲明
declare namespace N {
    function foo(x: number): number
}

import * as m from "module"
console.log("N.foo called: ", N.foo(42))

相關(guān)約束

  • 不支持ambient module聲明
  • 不支持通用模塊定義(UMD)
  • 模塊標(biāo)識符中不允許使用.js擴(kuò)展名

不支持通用模塊定義(UMD)

規(guī)則:arkts-no-umd

級別:錯(cuò)誤

ArkTS不支持通用模塊定義(UMD),。因?yàn)樵贏rkTS中沒有“腳本”的概念(相對于“模塊”),。此外,在ArkTS中,導(dǎo)入是編譯時(shí)而非運(yùn)行時(shí)特性。改用exportimport語法,。

TypeScript

// math-lib.d.ts
export const isPrime(x: number): boolean
export as namespace mathLib

// 腳本中
mathLib.isPrime(2)

ArkTS

// math-lib.d.ts
namespace mathLib {
    export isPrime(x: number): boolean
}

// 程序中
import { mathLib } from "math-lib"
mathLib.isPrime(2)

相關(guān)約束

  • 不支持在模塊名中使用通配符

模塊標(biāo)識符中不允許使用.js擴(kuò)展名

規(guī)則:arkts-no-js-extension

級別:錯(cuò)誤

ArkTS不允許在模塊標(biāo)識符中使用.js擴(kuò)展名,因?yàn)锳rkTS本身有與JavaScript交互的機(jī)制,。

TypeScript

import { something } from "module.js"

ArkTS

import { something } from "module"

相關(guān)約束

  • 不支持ambient module聲明
  • 不支持在模塊名中使用通配符

不支持new.target

規(guī)則:arkts-no-new-target

級別:錯(cuò)誤

ArkTS沒有原型的概念,因此不支持new.target。此特性不符合靜態(tài)類型的原則,。

TypeScript

class CustomError extends Error {
    constructor(message?: string) {
        // 'Error'在此處斷開原型鏈
        super(message)

        // 恢復(fù)原型鏈
        Object.setPrototypeOf(this, new.target.prototype)
    }
}

ArkTS

class CustomError extends Error {
    constructor(message?: string) {
        // 調(diào)用父類構(gòu)造函數(shù),繼承鏈?zhǔn)庆o態(tài)的,且不能在運(yùn)行時(shí)被改變
        super(message)
        console.log(this instanceof Error) // true
    }
}
let ce = new CustomError()

相關(guān)約束

  • 不支持在原型上賦值

不支持確定賦值斷言

規(guī)則:arkts-no-definite-assignment

級別:錯(cuò)誤

ArkTS不支持確定賦值斷言let v!: T,這是一種過度的編譯器提示,。改用帶初始化的聲明。

TypeScript

let x!: number // 提示:在使用前將x初始化

initialize()

function initialize() {
    x = 10
}

console.log("x = " + x)

ArkTS

function initialize() : number {
    return 10
}

let x: number = initialize()

console.log("x = " + x)

不支持IIFE(立即調(diào)用函數(shù)表達(dá)式)作為命名空間的聲明

規(guī)則:arkts-no-iife

級別:錯(cuò)誤

由于在ArkTS中,匿名函數(shù)不能作為命名空間,因此不支持IIFE作為命名空間的聲明,。請使用命名空間的常規(guī)語法,。

TypeScript

const C = (function () {
    class Cl {
        static static_value = "static_value";
        static any_value: any = "any_value";
        string_field = "string_field";
    }

    return Cl;
})();

C.prop = 2;

ArkTS

namespace C {
    // ...
}

不支持在原型上賦值

規(guī)則:arkts-no-prototype-assignment

級別:錯(cuò)誤

ArkTS沒有原型的概念,因此不支持在原型上賦值。此特性不符合靜態(tài)類型的原則,。

TypeScript

var C = function(p) {
    this.p = p // 只有在開啟noImplicitThis選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
}

C.prototype = {
    m() {
        console.log(this.p)
    }
}

C.prototype.q = function(r: number) {
    return this.p == r
}

ArkTS

class C {
    p: number = 0
    m() {
        console.log(this.p)
    }
    q(r: number) {
        return this.p == r
    }
}

相關(guān)約束

  • 不支持new.target

不支持globalThis

規(guī)則:arkts-no-globalthis

級別:錯(cuò)誤

由于ArkTS不支持動(dòng)態(tài)更改對象的布局,因此不支持全局作用域和globalThis,。

TypeScript

// 全局文件中
var abc = 100

// 從上面引用'abc'
globalThis.abc = 200

ArkTS

// file1
export let abc : number = 0

// file2
import * as M from "file1"

M.abc = 200

相關(guān)約束

  • 不支持聲明函數(shù)的屬性
  • 標(biāo)準(zhǔn)庫使用限制

不支持一些utility類型

規(guī)則:arkts-no-utility-types

級別:錯(cuò)誤

ArkTS僅支持PartialRecord,不支持TypeScript中其他的Utility Types

對于Record<K, V>類型,表達(dá)式rec[index]的類型是V | undefined,。
對于Record類型,鍵-值中的值的類型必須是可選類型或者包含undefined的聯(lián)合類型,。

TypeScript

type Person = {
    name: string
    age: number
    location: string
}

type QuantumPerson = Omit<Person, "location">

let persons : Record<string, Person> = {
    "Alice": {
        name: "Alice",
        age: 32,
        location: "Shanghai"
    },
    "Bob": {
        name: "Bob",
        age: 48,
        location: "New York"
    }
}
console.log(persons["Bob"].age)
console.log(persons["Rob"].age) // 運(yùn)行時(shí)異常

ArkTS

class Person {
    name: string = ""
    age: number = 0
    location: string = ""
}

class QuantumPerson {
    name: string = ""
    age: number = 0
}

type OptionalPerson = Person | undefined
let persons : Record<string, OptionalPerson> = {
// 或者
// let persons : Record<string, Person | undefined> = {
    "Alice": {
        name: "Alice",
        age: 32,
        location: "Shanghai"
    },
    "Bob": {
        name: "Bob",
        age: 48,
        location: "New York"
    }
}
console.log(persons["Bob"]!.age)
if (persons["Rob"]) { // 值檢查,不會運(yùn)行時(shí)拋異常
    console.log(persons["Rob"].age)
}

不支持對函數(shù)聲明屬性

規(guī)則:arkts-no-func-props

級別:錯(cuò)誤

由于ArkTS不支持動(dòng)態(tài)改變函數(shù)對象布局,因此,不支持對函數(shù)聲明屬性。

TypeScript

class MyImage {
    // ...
}

function readImage(
    path: string, callback: (err: any, image: MyImage) => void
)
{
    // ...
}

function readFileSync(path : string) : number[] {
    return []
}

function decodeImageSync(contrents : number[]) {
    // ...
}

readImage.sync = (path: string) => {
    const contents = readFileSync(path)
    return decodeImageSync(contents)
}

ArkTS

class MyImage {
    // ...
}

async function readImage(
    path: string, callback: (err: Error, image: MyImage) => void
) : Promise<MyImage>
{
    return await new MyImage()
}

function readImageSync(path: string) : MyImage {
    return new MyImage()
}

相關(guān)約束

  • 不支持globalThis

不支持Function.apply,、Function.bind以及Function.call

規(guī)則:arkts-no-func-apply-bind-call

級別:錯(cuò)誤

ArkTS不允許使用標(biāo)準(zhǔn)庫函數(shù)Function.apply,、Function.bind以及Function.call。標(biāo)準(zhǔn)庫使用這些函數(shù)來顯式設(shè)置被調(diào)用函數(shù)的this參數(shù),。在ArkTS中,this的語義僅限于傳統(tǒng)的OOP風(fēng)格,函數(shù)體中禁止使用this,。

TypeScript

class P1 {
  firstName: string = "Mary";
}

class P2 {
  firstName: string = "Jack";
  fullName(): string {
    return this.firstName
  }
}

const person2 = new P2();

const person1 = new P1();
// 將會打印 Mary
console.log(person2.fullName.apply(person1))

ArkTS

class Person {
    firstName : string

    constructor(firstName : string) {
        this.firstName = firstName
    }
    fullName() : string {
        return this.firstName
    }
}

let person = new Person("")
let person1 = new Person("Mary")

// 將打印“Mary”
console.log(person1.fullName())

相關(guān)約束

  • 不支持在函數(shù)中使用this

不支持readonly修飾函數(shù)參數(shù)

規(guī)則:arkts-no-readonly-params

級別:錯(cuò)誤

當(dāng)前ArkTS中,readonly可以用于修飾屬性,但不能用于修飾函數(shù)參數(shù)。

TypeScript

function foo(arr: readonly string[]) {
    arr.slice()        // OK
    arr.push("hello!") // 編譯時(shí)錯(cuò)誤
}

ArkTS

function foo(arr: string[]) {
    arr.slice()        // OK
    arr.push("hello!") // OK
}

不支持as const斷言

規(guī)則:arkts-no-as-const

級別:錯(cuò)誤

ArkTS不支持as const斷言,。在標(biāo)準(zhǔn)TypeScript中,as const用于標(biāo)注字面量的相應(yīng)字面量類型,而ArkTS不支持字面量類型,。

TypeScript

// 'hello'類型
let x = "hello" as const

// 'readonly [10, 20]'類型
let y = [10, 20] as const

// '{ readonly text: "hello" }'類型
let z = { text: "hello" } as const

ArkTS

// 'string'類型
let x : string = "hello"

// 'number[]'類型
let y : number[] = [10, 20]

class Label {
    text : string = ""
}

// 'Label'類型
let z : Label = {
    text: "hello"
}

不支持導(dǎo)入斷言

規(guī)則: arkts-no-import-assertions

級別:錯(cuò)誤

由于在ArkTS中,導(dǎo)入是編譯時(shí)而非運(yùn)行時(shí)特性,因此,ArkTS不支持導(dǎo)入斷言。在運(yùn)行時(shí)檢查導(dǎo)入的API是否正確,對于靜態(tài)類型的語言來說是沒有意義的,。改用常規(guī)的import語法,。

TypeScript

import { obj } from "something.json" assert { type: "json" }

ArkTS

// 編譯時(shí)將檢查導(dǎo)入T的正確性
import { something } from "module"

相關(guān)約束

  • 不支持在模塊名中使用通配符
  • 不支持通用模塊定義(UMD)
  • 不支持運(yùn)行時(shí)導(dǎo)入斷言

限制使用標(biāo)準(zhǔn)庫

規(guī)則:arkts-limited-stdlib

級別:錯(cuò)誤

ArkTS不允許使用TypeScript或JavaScript標(biāo)準(zhǔn)庫中的某些接口,。大部分接口與動(dòng)態(tài)特性有關(guān)。ArkTS中禁止使用以下接口:

全局對象的屬性和方法:eval,、
Infinity,、NaNisFinite,、isNaN,、parseFloatparseInt,、
Encode,、DecodeParseHexOctet

Object__proto__,、__defineGetter__,、__defineSetter__
__lookupGetter__,、__lookupSetter__,、assigncreate,、
defineProperties,、definePropertyentries,、freeze,、
fromEntriesgetOwnPropertyDescriptor,、getOwnPropertyDescriptors,、
getOwnPropertyNamesgetOwnPropertySymbols,、getPrototypeOf,、
hasOwnhasOwnProperty,、is,、isExtensibleisFrozen,、
isPrototypeOf,、isSealedkeys,、preventExtensions,、
propertyIsEnumerableseal,、setPrototypeOf,、values

Reflectapply,、constructdefineProperty,、deleteProperty,、
getgetOwnPropertyDescriptor,、getPrototypeOf,、has
isExtensible,、ownKeys,、preventExtensions,、set,
setPrototypeOf

Proxyhandler.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()

ArrayisArray

ArrayBufferisView

相關(guān)約束

  • 對象的屬性名必須是合法的標(biāo)識符
  • 不支持Symbol() API
  • 不支持通過索引訪問字段
  • 僅允許在表達(dá)式中使用typeof運(yùn)算符
  • 不支持in運(yùn)算符
  • 禁止運(yùn)行時(shí)檢查對象屬性
  • 不支持globalThis

強(qiáng)制開啟嚴(yán)格類型檢查

規(guī)則:arkts-strict-typing

級別:錯(cuò)誤

在ArkTS中,以下TypeScript的嚴(yán)格類型檢查選項(xiàng)必須打開:noImplicitReturns,
strictFunctionTypes, strictNullChecks, strictPropertyInitialization,。

TypeScript

class C {
    n: number // 只有在開啟strictPropertyInitialization選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
    s: string // 只有在開啟strictPropertyInitialization選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
}

// 只有在開啟noImplicitReturns選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤
function foo(s: string): string {
    if (s != "") {
        console.log(s)
        return s
    } else {
        console.log(s)
    }
}

let n: number = null // 只有在開啟strictNullChecks選項(xiàng)時(shí)會產(chǎn)生編譯時(shí)錯(cuò)誤

ArkTS

class C {
    n: number = 0
    s: string = ""
}

function foo(s: string): string {
    console.log(s)
    return s
}

let n1: number | null = null
let n2: number = 0

相關(guān)約束

  • 使用具體的類型而非any或unknown
  • 不允許通過注釋關(guān)閉類型檢查

不允許通過注釋關(guān)閉類型檢查

規(guī)則:arkts-strict-typing-required

級別:錯(cuò)誤

在ArkTS中,類型檢查不是可選項(xiàng)。不允許通過注釋關(guān)閉類型檢查,不支持使用@ts-ignore@ts-nocheck,。

TypeScript

// @ts-nocheck
// ...
// 關(guān)閉了類型檢查后的代碼
// ...

let s1: string = null // 沒有報(bào)錯(cuò)

// @ts-ignore
let s2: string = null // 沒有報(bào)錯(cuò)

ArkTS

let s1: string | null = null // 沒有報(bào)錯(cuò),合適的類型
let s2: string = null // 編譯時(shí)報(bào)錯(cuò)

相關(guān)約束

  • 使用具體的類型而非any或unknown
  • 強(qiáng)制開啟嚴(yán)格類型檢查

允許ArkTS代碼導(dǎo)入TS代碼, 不允許TS代碼導(dǎo)入ArkTS代碼

規(guī)則:arkts-no-ts-deps

級別:錯(cuò)誤

ArkTS中的代碼可以導(dǎo)入來自標(biāo)準(zhǔn)TypeScript的代碼,而標(biāo)準(zhǔn)TypeScript的代碼不能導(dǎo)入來自ArkTS中的代碼,。

TypeScript

// app.ets
export class C {
    // ...
}

// lib.ts
import { C } from "app"

ArkTS

// lib1.ets
export class C {
    // ...
}

// lib2.ets
import { C } from "lib1"

除了ArkUI中的裝飾器,不允許使用其他裝飾器

規(guī)則:arkts-no-decorators-except-arkui

級別:錯(cuò)誤

現(xiàn)在,ArkTS中只支持ArkUI中的裝飾器。使用其他裝飾器會造成編譯時(shí)錯(cuò)誤,。

TypeScript

function classDecorator(x: number, y: number): void {
    //
}

@classDecorator
class BugReport {
}

ArkTS

function classDecorator(x: number, y: number): void {
    //
}

@classDecorator // 編譯時(shí)錯(cuò)誤
class BugReport {
}

class不能被用作對象

規(guī)則:arkts-no-classes-as-obj

級別:錯(cuò)誤

在ArkTS中,class聲明的是一個(gè)新的類型,不是一個(gè)值,。因此,不支持將class用作對象(例如將class賦值給一個(gè)對象)。

TypeScript

class C {
    s: string = ""
    n: number = 0
}

let c = C

不支持在import語句前使用其他語句

規(guī)則:arkts-no-misplaced-imports

級別:錯(cuò)誤

在ArkTS中,除動(dòng)態(tài)import語句外,所有import語句需要放在所有其他語句之前,。

TypeScript

class C {
    s: string = ""
    n: number = 0
}

import foo from "module1"

ArkTS

import foo from "module1"

class C {
    s: string = ""
    n: number = 0
}

參考:

https:///openharmony/docs/blob/master/zh-cn/application-dev/quick-start/typescript-to-arkts-migration-guide.md#%E7%BA%A6%E6%9D%9F%E8%AF%B4%E6%98%8E

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多