13af6ab5fSopenharmony_ci#  Structural typing is not supported
23af6ab5fSopenharmony_ci
33af6ab5fSopenharmony_ciRule ``arkts-no-structural-typing``
43af6ab5fSopenharmony_ci
53af6ab5fSopenharmony_ci**Severity: error**
63af6ab5fSopenharmony_ci
73af6ab5fSopenharmony_ciCurrently, ArkTS does not support structural typing, i.e., the compiler
83af6ab5fSopenharmony_cicannot compare public APIs of two types and decide whether such types are
93af6ab5fSopenharmony_ciidentical. Use other mechanisms (inheritance, interfaces or type aliases)
103af6ab5fSopenharmony_ciinstead.
113af6ab5fSopenharmony_ci
123af6ab5fSopenharmony_ci
133af6ab5fSopenharmony_ci## TypeScript
143af6ab5fSopenharmony_ci
153af6ab5fSopenharmony_ci
163af6ab5fSopenharmony_ci```
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_ci    interface I1 {
193af6ab5fSopenharmony_ci        f(): string
203af6ab5fSopenharmony_ci    }
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_ci    interface I2 { // I2 is structurally equivalent to I1
233af6ab5fSopenharmony_ci        f(): string
243af6ab5fSopenharmony_ci    }
253af6ab5fSopenharmony_ci
263af6ab5fSopenharmony_ci    class X {
273af6ab5fSopenharmony_ci        n: number = 0
283af6ab5fSopenharmony_ci        s: string = ""
293af6ab5fSopenharmony_ci    }
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_ci    class Y { // Y is structurally equivalent to X
323af6ab5fSopenharmony_ci        n: number = 0
333af6ab5fSopenharmony_ci        s: string = ""
343af6ab5fSopenharmony_ci    }
353af6ab5fSopenharmony_ci
363af6ab5fSopenharmony_ci    let x = new X()
373af6ab5fSopenharmony_ci    let y = new Y()
383af6ab5fSopenharmony_ci
393af6ab5fSopenharmony_ci    console.log("Assign X to Y")
403af6ab5fSopenharmony_ci    y = x
413af6ab5fSopenharmony_ci
423af6ab5fSopenharmony_ci    console.log("Assign Y to X")
433af6ab5fSopenharmony_ci    x = y
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_ci    function foo(x: X) {
463af6ab5fSopenharmony_ci        console.log(x.n, x.s)
473af6ab5fSopenharmony_ci    }
483af6ab5fSopenharmony_ci
493af6ab5fSopenharmony_ci    // X and Y are equivalent because their public API is equivalent.
503af6ab5fSopenharmony_ci    // Thus the second call is allowed:
513af6ab5fSopenharmony_ci    foo(new X())
523af6ab5fSopenharmony_ci    foo(new Y())
533af6ab5fSopenharmony_ci
543af6ab5fSopenharmony_ci```
553af6ab5fSopenharmony_ci
563af6ab5fSopenharmony_ci## ArkTS
573af6ab5fSopenharmony_ci
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci```
603af6ab5fSopenharmony_ci
613af6ab5fSopenharmony_ci    interface I1 {
623af6ab5fSopenharmony_ci        f(): string
633af6ab5fSopenharmony_ci    }
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_ci    type I2 = I1 // I2 is an alias for I1
663af6ab5fSopenharmony_ci
673af6ab5fSopenharmony_ci    class B {
683af6ab5fSopenharmony_ci        n: number = 0
693af6ab5fSopenharmony_ci        s: string = ""
703af6ab5fSopenharmony_ci    }
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_ci    // D is derived from B, which explicitly set subtype / supertype relations:
733af6ab5fSopenharmony_ci    class D extends B {
743af6ab5fSopenharmony_ci        constructor() {
753af6ab5fSopenharmony_ci            super()
763af6ab5fSopenharmony_ci        }
773af6ab5fSopenharmony_ci    }
783af6ab5fSopenharmony_ci
793af6ab5fSopenharmony_ci    let b = new B()
803af6ab5fSopenharmony_ci    let d = new D()
813af6ab5fSopenharmony_ci
823af6ab5fSopenharmony_ci    console.log("Assign D to B")
833af6ab5fSopenharmony_ci    b = d // ok, B is the superclass of D
843af6ab5fSopenharmony_ci
853af6ab5fSopenharmony_ci    // An attempt to assign b to d will result in a compile-time error:
863af6ab5fSopenharmony_ci    // d = b
873af6ab5fSopenharmony_ci
883af6ab5fSopenharmony_ci    interface Common {
893af6ab5fSopenharmony_ci       n: number
903af6ab5fSopenharmony_ci       s: string
913af6ab5fSopenharmony_ci    }
923af6ab5fSopenharmony_ci
933af6ab5fSopenharmony_ci    // X implements interface Z, which makes relation between X and Y explicit.
943af6ab5fSopenharmony_ci    class X implements Common {
953af6ab5fSopenharmony_ci        n: number = 0
963af6ab5fSopenharmony_ci        s: string = ""
973af6ab5fSopenharmony_ci    }
983af6ab5fSopenharmony_ci
993af6ab5fSopenharmony_ci    // Y implements interface Z, which makes relation between X and Y explicit.
1003af6ab5fSopenharmony_ci    class Y implements Common {
1013af6ab5fSopenharmony_ci        n: number = 0
1023af6ab5fSopenharmony_ci        s: string = ""
1033af6ab5fSopenharmony_ci    }
1043af6ab5fSopenharmony_ci
1053af6ab5fSopenharmony_ci    let x: Common = new X()
1063af6ab5fSopenharmony_ci    let y: Common = new Y()
1073af6ab5fSopenharmony_ci
1083af6ab5fSopenharmony_ci    console.log("Assign X to Y")
1093af6ab5fSopenharmony_ci    y = x // ok, both are of the same type
1103af6ab5fSopenharmony_ci
1113af6ab5fSopenharmony_ci    console.log("Assign Y to X")
1123af6ab5fSopenharmony_ci    x = y // ok, both are of the same type
1133af6ab5fSopenharmony_ci
1143af6ab5fSopenharmony_ci    function foo(c: Common): void {
1153af6ab5fSopenharmony_ci        console.log(c.n, c.s)
1163af6ab5fSopenharmony_ci    }
1173af6ab5fSopenharmony_ci
1183af6ab5fSopenharmony_ci    // X and Y implement the same interface, thus both calls are allowed:
1193af6ab5fSopenharmony_ci    foo(new X())
1203af6ab5fSopenharmony_ci    foo(new Y())
1213af6ab5fSopenharmony_ci
1223af6ab5fSopenharmony_ci```
1233af6ab5fSopenharmony_ci
1243af6ab5fSopenharmony_ci
125