From 949263453b391c039dc9b6c5a92dc260e25bb1dd Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Fri, 4 Aug 2023 01:26:10 +0300 Subject: [PATCH 1/9] [TS Linter] fix issue#12945 and update to CookBook version #222 Signed-off-by: Igor Rossinski --- linter-4.2/.gitignore | 1 + linter-4.2/docs/rules/recipe1.md | 2 +- linter-4.2/docs/rules/recipe118.md | 6 +-- linter-4.2/docs/rules/recipe123.md | 61 ----------------------- linter-4.2/docs/rules/recipe128.md | 2 +- linter-4.2/docs/rules/recipe130.md | 2 +- linter-4.2/docs/rules/recipe131.md | 4 +- linter-4.2/docs/rules/recipe133.md | 4 +- linter-4.2/docs/rules/recipe135.md | 5 +- linter-4.2/docs/rules/recipe136.md | 2 +- linter-4.2/docs/rules/recipe137.md | 2 +- linter-4.2/docs/rules/recipe138.md | 48 ++++++++++++++++-- linter-4.2/docs/rules/recipe139.md | 8 +-- linter-4.2/docs/rules/recipe142.md | 2 +- linter-4.2/docs/rules/recipe143.md | 4 +- linter-4.2/docs/rules/recipe145.md | 14 ++++-- linter-4.2/docs/rules/recipe146.md | 5 +- linter-4.2/docs/rules/recipe147.md | 3 +- linter-4.2/docs/rules/recipe17.md | 2 +- linter-4.2/docs/rules/recipe2.md | 2 +- linter-4.2/docs/rules/recipe24.md | 46 ----------------- linter-4.2/docs/rules/recipe33.md | 58 --------------------- linter-4.2/docs/rules/recipe40.md | 4 +- linter-4.2/docs/rules/recipe45.md | 3 +- linter-4.2/docs/rules/recipe51.md | 2 +- linter-4.2/docs/rules/recipe52.md | 2 +- linter-4.2/docs/rules/recipe59.md | 4 +- linter-4.2/docs/rules/recipe69.md | 6 +-- linter-4.2/docs/rules/recipe79.md | 8 ++- linter-4.2/docs/rules/recipe90.md | 2 + linter-4.2/docs/rules/recipe93.md | 2 +- linter-4.2/src/TypeScriptLinter.ts | 6 +++ linter-4.2/test/instanceof.ts | 10 ++++ linter-4.2/test/instanceof.ts.relax.json | 20 ++++++++ linter-4.2/test/instanceof.ts.strict.json | 20 ++++++++ linter/.gitignore | 1 + linter/docs/rules/recipe1.md | 2 +- linter/docs/rules/recipe118.md | 6 +-- linter/docs/rules/recipe128.md | 2 +- linter/docs/rules/recipe130.md | 2 +- linter/docs/rules/recipe131.md | 4 +- linter/docs/rules/recipe133.md | 4 +- linter/docs/rules/recipe135.md | 5 +- linter/docs/rules/recipe136.md | 2 +- linter/docs/rules/recipe137.md | 2 +- linter/docs/rules/recipe138.md | 48 ++++++++++++++++-- linter/docs/rules/recipe139.md | 8 +-- linter/docs/rules/recipe142.md | 2 +- linter/docs/rules/recipe143.md | 4 +- linter/docs/rules/recipe145.md | 14 ++++-- linter/docs/rules/recipe146.md | 5 +- linter/docs/rules/recipe147.md | 3 +- linter/docs/rules/recipe17.md | 2 +- linter/docs/rules/recipe2.md | 2 +- linter/docs/rules/recipe40.md | 4 +- linter/docs/rules/recipe45.md | 3 +- linter/docs/rules/recipe51.md | 2 +- linter/docs/rules/recipe52.md | 2 +- linter/docs/rules/recipe59.md | 4 +- linter/docs/rules/recipe69.md | 6 +-- linter/docs/rules/recipe79.md | 8 ++- linter/docs/rules/recipe90.md | 2 + linter/docs/rules/recipe93.md | 2 +- linter/src/TypeScriptLinter.ts | 6 +++ linter/test/instanceof.ts | 10 ++++ linter/test/instanceof.ts.relax.json | 20 ++++++++ linter/test/instanceof.ts.strict.json | 20 ++++++++ 67 files changed, 318 insertions(+), 261 deletions(-) delete mode 100644 linter-4.2/docs/rules/recipe123.md delete mode 100644 linter-4.2/docs/rules/recipe24.md delete mode 100644 linter-4.2/docs/rules/recipe33.md diff --git a/linter-4.2/.gitignore b/linter-4.2/.gitignore index 3ded455fc..4797db793 100644 --- a/linter-4.2/.gitignore +++ b/linter-4.2/.gitignore @@ -2,6 +2,7 @@ build dist bundle node_modules +cookbook_convertor/md *.tsbuildinfo .vs .vscode diff --git a/linter-4.2/docs/rules/recipe1.md b/linter-4.2/docs/rules/recipe1.md index 317d04c6b..cda73e56f 100644 --- a/linter-4.2/docs/rules/recipe1.md +++ b/linter-4.2/docs/rules/recipe1.md @@ -27,7 +27,7 @@ data by numeric indices. ``` class X { - public name: number + public name: number = 0 } let x = {name: 1} console.log(x.name) diff --git a/linter-4.2/docs/rules/recipe118.md b/linter-4.2/docs/rules/recipe118.md index 0041552fd..f625bc3e9 100644 --- a/linter-4.2/docs/rules/recipe118.md +++ b/linter-4.2/docs/rules/recipe118.md @@ -14,10 +14,10 @@ Use ordinary import instead. ``` // Re-using the same import - import { APIResponseType } from "./api" + import { APIResponseType } from "api" // Explicitly use import type - import type { APIResponseType } from "./api" + import type { APIResponseType } from "api" ``` @@ -26,7 +26,7 @@ Use ordinary import instead. ``` - import { APIResponseType } from "./api" + import { APIResponseType } from "api" ``` diff --git a/linter-4.2/docs/rules/recipe123.md b/linter-4.2/docs/rules/recipe123.md deleted file mode 100644 index 936673738..000000000 --- a/linter-4.2/docs/rules/recipe123.md +++ /dev/null @@ -1,61 +0,0 @@ -# Renaming in export declarations is not supported - -Rule ``arkts-no-export-renaming`` - -**Severity: error** - -ArkTS does not support renaming in export declarations. Similar effect -can be achieved through setting an alias for the exported entity. - - -## TypeScript - - -``` - - // file1.ts - class MyClass { - // ... - } - - export { MyClass as RenamedClass } - - // file2.ts - import { RenamedClass } from "./file1" - - function main(): void { - const myObject = new RenamedClass() - // ... - } - -``` - -## ArkTS - - -``` - - // module1 - class MyClass { - // ... - } - - export type RenamedClass = MyClass - - // module2 - import { RenamedClass } from "./module1" - - function main(): void { - const myObject = new RenamedClass() - // ... - } - -``` - -## See also - -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 125: Re-exporting is not supported (``arkts-no-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter-4.2/docs/rules/recipe128.md b/linter-4.2/docs/rules/recipe128.md index 9a5ccebd4..ddba6753b 100644 --- a/linter-4.2/docs/rules/recipe128.md +++ b/linter-4.2/docs/rules/recipe128.md @@ -25,7 +25,7 @@ own mechanisms for interoperating with JavaScript. ``` // Import what you need from the original module - import { normalize } from "../someModule" + import { normalize } from "someModule" ``` diff --git a/linter-4.2/docs/rules/recipe130.md b/linter-4.2/docs/rules/recipe130.md index da2aada01..4a5c602e6 100644 --- a/linter-4.2/docs/rules/recipe130.md +++ b/linter-4.2/docs/rules/recipe130.md @@ -35,7 +35,7 @@ import is a compile-time, not a runtime feature. Use ordinary syntax for } // in program - import { mathLib } from "./math-lib" + import { mathLib } from "math-lib" mathLib.isPrime(2) ``` diff --git a/linter-4.2/docs/rules/recipe131.md b/linter-4.2/docs/rules/recipe131.md index c9f6e9c22..a103967cd 100644 --- a/linter-4.2/docs/rules/recipe131.md +++ b/linter-4.2/docs/rules/recipe131.md @@ -13,7 +13,7 @@ has its own mechanisms for interoperating with JavaScript. ``` - import { something } from "./module.js" + import { something } from "module.js" ``` @@ -22,7 +22,7 @@ has its own mechanisms for interoperating with JavaScript. ``` - import { something } from "./module" + import { something } from "module" ``` diff --git a/linter-4.2/docs/rules/recipe133.md b/linter-4.2/docs/rules/recipe133.md index 222bfdee0..ab2f0a51e 100644 --- a/linter-4.2/docs/rules/recipe133.md +++ b/linter-4.2/docs/rules/recipe133.md @@ -14,7 +14,7 @@ import syntax instead. ``` - const zipUtil = await import("./utils/create-zip-file") + const zipUtil = await import("utils/create-zip-file") ``` @@ -23,7 +23,7 @@ import syntax instead. ``` - import { zipUtil } from "./utils/create-zip-file" + import { zipUtil } from "utils/create-zip-file" ``` diff --git a/linter-4.2/docs/rules/recipe135.md b/linter-4.2/docs/rules/recipe135.md index 545a49b9b..5e7bb8835 100644 --- a/linter-4.2/docs/rules/recipe135.md +++ b/linter-4.2/docs/rules/recipe135.md @@ -15,9 +15,10 @@ namespaces instead. ``` var C = (function() { - function C(n) { - this.p = n + function C(n: number) { + this.p = n // Compile-time error only with noImplicitThis } + C.staticProperty = 0 return C })() C.staticProperty = 1 diff --git a/linter-4.2/docs/rules/recipe136.md b/linter-4.2/docs/rules/recipe136.md index eb2ada706..550b95b54 100644 --- a/linter-4.2/docs/rules/recipe136.md +++ b/linter-4.2/docs/rules/recipe136.md @@ -15,7 +15,7 @@ applicable to the static typing. ``` var C = function(p) { - this.p = p + this.p = p // Compile-time error only with noImplicitThis } C.prototype = { diff --git a/linter-4.2/docs/rules/recipe137.md b/linter-4.2/docs/rules/recipe137.md index 588cc70f4..5cb8d691d 100644 --- a/linter-4.2/docs/rules/recipe137.md +++ b/linter-4.2/docs/rules/recipe137.md @@ -30,7 +30,7 @@ objects with dynamically changed layout are not supported. export let abc : number = 0 // file2 - import * as M from "../file1" + import * as M from "file1" M.abc = 200 diff --git a/linter-4.2/docs/rules/recipe138.md b/linter-4.2/docs/rules/recipe138.md index f97ec50ae..7dfec46f8 100644 --- a/linter-4.2/docs/rules/recipe138.md +++ b/linter-4.2/docs/rules/recipe138.md @@ -8,6 +8,9 @@ Currently ArkTS does not support utility types from TypeScript extensions to the standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``Record``. +For ``Record`` type, the type of value must be either optional or unioned with +the ``undefined`` type. + ## TypeScript @@ -22,6 +25,21 @@ standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, type QuantumPerson = Omit + let persons : Record = { + "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) // Runtime exception + ``` ## ArkTS @@ -30,14 +48,34 @@ standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``` class Person { - name: string - age: number - location: string + name: string = "" + age: number = 0 + location: string = "" } class QuantumPerson { - name: string - age: number + name: string = "" + age: number = 0 + } + + type OptionalPerson = Person | undefined + let persons : Record = { + // Or: + // let persons : Record = { + "Alice": { + name: "Alice", + age: 32, + location: "Shanghai" + }, + "Bob": { + name: "Bob", + age: 48, + location: "New York" + } + } + console.log(persons["Bob"]!.age) + if (persons["Rob"]) { // Explicit value check, no runtime exception + console.log(persons["Rob"].age) } ``` diff --git a/linter-4.2/docs/rules/recipe139.md b/linter-4.2/docs/rules/recipe139.md index 5b27d1ebf..70fd68966 100644 --- a/linter-4.2/docs/rules/recipe139.md +++ b/linter-4.2/docs/rules/recipe139.md @@ -49,15 +49,17 @@ this rule and their layout cannot be changed in runtime. // ... } - function readImage( + async function readImage( path: string, callback: (err: Error, image: MyImage) => void ) : Promise { - // async implementation + // In real world, the implementation is more complex, + // involving real network / DB logic, etc. + return await new MyImage() } function readImageSync(path: string) : MyImage { - // sync implementation + return new MyImage() } ``` diff --git a/linter-4.2/docs/rules/recipe142.md b/linter-4.2/docs/rules/recipe142.md index cca78dc76..7cef054e7 100644 --- a/linter-4.2/docs/rules/recipe142.md +++ b/linter-4.2/docs/rules/recipe142.md @@ -37,7 +37,7 @@ does not support literal types. let y : number[] = [10, 20] class Label { - text : string + text : string = "" } // Type 'Label': diff --git a/linter-4.2/docs/rules/recipe143.md b/linter-4.2/docs/rules/recipe143.md index 946b66efa..9dbec44af 100644 --- a/linter-4.2/docs/rules/recipe143.md +++ b/linter-4.2/docs/rules/recipe143.md @@ -15,7 +15,7 @@ in runtime does not make sense for the statically typed language. Use ordinary ``` - import { obj } from "./something.json" assert { type: "json" } + import { obj } from "something.json" assert { type: "json" } ``` @@ -25,7 +25,7 @@ in runtime does not make sense for the statically typed language. Use ordinary ``` // Correctness of importing T will be checked in compile-time: - import { something } from "./module" + import { something } from "module" ``` diff --git a/linter-4.2/docs/rules/recipe145.md b/linter-4.2/docs/rules/recipe145.md index 37e7be51f..26464d5d8 100644 --- a/linter-4.2/docs/rules/recipe145.md +++ b/linter-4.2/docs/rules/recipe145.md @@ -16,15 +16,21 @@ following flags should be turned on: ``noImplicitReturns``, ``` class C { - n: number - s: string + n: number // Compile-time error only with strictPropertyInitialization + s: string // Compile-time error only with strictPropertyInitialization } + // Compile-time error only with noImplicitReturns function foo(s: string): string { - console.log(s) + if (s != "") { + console.log(s) + return s + } else { + console.log(s) + } } - let n: number = null + let n: number = null // Compile-time error only with strictNullChecks ``` diff --git a/linter-4.2/docs/rules/recipe146.md b/linter-4.2/docs/rules/recipe146.md index f00a66b15..7ec5432f3 100644 --- a/linter-4.2/docs/rules/recipe146.md +++ b/linter-4.2/docs/rules/recipe146.md @@ -20,9 +20,10 @@ with special comments is not allowed. In particular, ``@ts-ignore`` and // Some code with switched off type checker // ... - // @ts-ignore let s1: string = null // No error, type checker suppressed - let s2: string = null // Compile-time error + + // @ts-ignore + let s2: string = null // No error, type checker suppressed ``` diff --git a/linter-4.2/docs/rules/recipe147.md b/linter-4.2/docs/rules/recipe147.md index 6a81f41c8..f3ca0e11f 100644 --- a/linter-4.2/docs/rules/recipe147.md +++ b/linter-4.2/docs/rules/recipe147.md @@ -20,8 +20,7 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" - + ``` - diff --git a/linter-4.2/docs/rules/recipe17.md b/linter-4.2/docs/rules/recipe17.md index 4dd591c0e..93066f260 100644 --- a/linter-4.2/docs/rules/recipe17.md +++ b/linter-4.2/docs/rules/recipe17.md @@ -32,7 +32,7 @@ ArkTS does not allow indexed signatures, use arrays instead. ``` class X { - public f: string[] + public f: string[] = [] } let myArray: X = new X() diff --git a/linter-4.2/docs/rules/recipe2.md b/linter-4.2/docs/rules/recipe2.md index 623cbff52..04a96f967 100644 --- a/linter-4.2/docs/rules/recipe2.md +++ b/linter-4.2/docs/rules/recipe2.md @@ -29,7 +29,7 @@ and cannot be changed at runtime. ``` class SomeClass { - public someProperty : string + public someProperty : string = "" } let o = new SomeClass() diff --git a/linter-4.2/docs/rules/recipe24.md b/linter-4.2/docs/rules/recipe24.md deleted file mode 100644 index 174d84055..000000000 --- a/linter-4.2/docs/rules/recipe24.md +++ /dev/null @@ -1,46 +0,0 @@ -# Optional parameters are not supported for primitive types - -Rule ``arkts-no-opt-params`` - -**Severity: error** - -ArkTS does not support optional parameters of primitive types. -You can use default parameter values or reference types. For reference types, -non-specified optional parameter is set to ``null``. - - -## TypeScript - - -``` - - // x is an optional parameter: - function f(x?: number) { - console.log(x) // log undefined or number - } - - // x is a required parameter with the default value: - function g(x: number = 1) { - console.log(x) - } - -``` - -## ArkTS - - -``` - - // You can use reference type (will be set to null if missing): - function f(x?: Number) { - console.log(x) // log null or some number - } - - // You can use a required parameter with the default value: - function g(x: number = 1) { - console.log(x) - } - -``` - - diff --git a/linter-4.2/docs/rules/recipe33.md b/linter-4.2/docs/rules/recipe33.md deleted file mode 100644 index 4b8adbb07..000000000 --- a/linter-4.2/docs/rules/recipe33.md +++ /dev/null @@ -1,58 +0,0 @@ -# Optional properties are not supported for primitive types - -Rule ``arkts-no-opt-props`` - -**Severity: error** - -ArkTS does not support optional properties of primitive types. You can use -properties with default values or reference types. For reference types, -non-specified optional property is set to ``null``. This rule applies both to -classes and interfaces. - - -## TypeScript - - -``` - - class CompilerOptions { - strict?: boolean - sourcePath?: string - targetPath?: string - } - - let options: CompilerOptions = { - strict: true, - sourcePath: "./src" - } - - if (options.targetPath == undefined) { - // Some logic - } - -``` - -## ArkTS - - -``` - - class CompilerOptions { - strict: boolean = false - sourcePath: string = "" - targetPath?: string - } - - let options: CompilerOptions = { - strict: true, - sourcePath: "./src" - // targetPath is implicitly set to null - } - - if (options.targetPath == null) { - // Some logic - } - -``` - - diff --git a/linter-4.2/docs/rules/recipe40.md b/linter-4.2/docs/rules/recipe40.md index 9fd22580f..dd4221b14 100644 --- a/linter-4.2/docs/rules/recipe40.md +++ b/linter-4.2/docs/rules/recipe40.md @@ -28,8 +28,8 @@ types in place. Declare classes and interfaces explicitly instead. ``` class O { - x: number - y: number + x: number = 0 + y: number = 0 } let o: O = {x: 2, y: 3} diff --git a/linter-4.2/docs/rules/recipe45.md b/linter-4.2/docs/rules/recipe45.md index 20680c932..70f14066e 100644 --- a/linter-4.2/docs/rules/recipe45.md +++ b/linter-4.2/docs/rules/recipe45.md @@ -13,7 +13,8 @@ to be explicitly specified. ``` - let f = (s) => { // type any is assumed + // Compile-time error only with noImplicitAny: + let f = (s /* type any is assumed */) => { console.log(s) } diff --git a/linter-4.2/docs/rules/recipe51.md b/linter-4.2/docs/rules/recipe51.md index 9b6ddc1fd..700a2409c 100644 --- a/linter-4.2/docs/rules/recipe51.md +++ b/linter-4.2/docs/rules/recipe51.md @@ -29,7 +29,7 @@ may be specified. ``` interface C { - foo() + foo(): void } class C1 implements C { diff --git a/linter-4.2/docs/rules/recipe52.md b/linter-4.2/docs/rules/recipe52.md index 91042ae77..f4ff3fd4b 100644 --- a/linter-4.2/docs/rules/recipe52.md +++ b/linter-4.2/docs/rules/recipe52.md @@ -19,7 +19,7 @@ existence during compilation. let n = person["name"] let e = person["isEmployee"] - let s = person["office"] // undefined + let s = person["office"] // Compile-time error only with noImplicitAny ``` diff --git a/linter-4.2/docs/rules/recipe59.md b/linter-4.2/docs/rules/recipe59.md index d64602e17..d2c937e46 100644 --- a/linter-4.2/docs/rules/recipe59.md +++ b/linter-4.2/docs/rules/recipe59.md @@ -32,8 +32,8 @@ changed at runtime. Thus the operation of deleting a property makes no sense. // and assign null to mark value absence: class Point { - x: number | null - y: number | null + x: number | null = 0 + y: number | null = 0 } let p = new Point() diff --git a/linter-4.2/docs/rules/recipe69.md b/linter-4.2/docs/rules/recipe69.md index 50d253b2f..80725b25c 100644 --- a/linter-4.2/docs/rules/recipe69.md +++ b/linter-4.2/docs/rules/recipe69.md @@ -34,11 +34,11 @@ using a temporary variable, where applicable) can be used for replacement. one = two two = tmp - let data: Number[] = [1,2,3,4] + let data: Number[] = [1, 2, 3, 4] let head = data[0] - let tail = new Number[data.length - 1] + let tail: Number[] = [] for (let i = 1; i < data.length; ++i) { - tail[i - 1] = data[i] + tail.push(data[i]) } ``` diff --git a/linter-4.2/docs/rules/recipe79.md b/linter-4.2/docs/rules/recipe79.md index 56ac1ea4f..15f916438 100644 --- a/linter-4.2/docs/rules/recipe79.md +++ b/linter-4.2/docs/rules/recipe79.md @@ -17,7 +17,9 @@ be omitted. try { // some code } - catch (a: unknown) {} + catch (a: unknown) { + // handle error + } ``` @@ -29,7 +31,9 @@ be omitted. try { // some code } - catch (a) {} + catch (a) { + // handle error + } ``` diff --git a/linter-4.2/docs/rules/recipe90.md b/linter-4.2/docs/rules/recipe90.md index 0613f6913..2ef93392a 100644 --- a/linter-4.2/docs/rules/recipe90.md +++ b/linter-4.2/docs/rules/recipe90.md @@ -16,6 +16,7 @@ explicitly. ``` + // Compile-time error with noImplicitAny function f(x: number) { if (x <= 0) { return x @@ -23,6 +24,7 @@ explicitly. return g(x) } + // Compile-time error with noImplicitAny function g(x: number) { return f(x - 1) } diff --git a/linter-4.2/docs/rules/recipe93.md b/linter-4.2/docs/rules/recipe93.md index ceb0cacf5..ab4bce316 100644 --- a/linter-4.2/docs/rules/recipe93.md +++ b/linter-4.2/docs/rules/recipe93.md @@ -14,7 +14,7 @@ ArkTS does not support the usage of ``this`` inside stand-alone functions. ``` function foo(i: number) { - this.count = i + this.count = i // Compile-time error only with noImplicitThis } class A { diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index ace430886..aad8f7d46 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1402,6 +1402,12 @@ export class TypeScriptLinter { !Utils.relatedByInheritanceOrIdentical(targetType, exprType) ) this.incrementCounters(tsAsExpr, FaultID.StructuralIdentity); + // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled + if( + ( Utils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' ) || + ( Utils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) + ) + this.incrementCounters(node, FaultID.InstanceofUnsupported); } private handleTypeReference(node: ts.Node) { diff --git a/linter-4.2/test/instanceof.ts b/linter-4.2/test/instanceof.ts index 7f04b131b..2289a2292 100644 --- a/linter-4.2/test/instanceof.ts +++ b/linter-4.2/test/instanceof.ts @@ -28,3 +28,13 @@ const e = (5.0 as number) instanceof Number; // false const f = (X | String) instanceof Object; const g = 3 instanceof Number; + + +let bad2Number = 5.0 as Number; +let pi = 3.14; +bad2Number = pi as Number; + +let bad2Boolean = true as Boolean; +let bad2Boolean = a as Boolean; + + diff --git a/linter-4.2/test/instanceof.ts.relax.json b/linter-4.2/test/instanceof.ts.relax.json index f9d548166..e63faa96a 100644 --- a/linter-4.2/test/instanceof.ts.relax.json +++ b/linter-4.2/test/instanceof.ts.relax.json @@ -33,6 +33,26 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" + }, + { + "line": 33, + "column": 18, + "problem": "InstanceofUnsupported" + }, + { + "line": 35, + "column": 14, + "problem": "InstanceofUnsupported" + }, + { + "line": 37, + "column": 19, + "problem": "InstanceofUnsupported" + }, + { + "line": 38, + "column": 19, + "problem": "InstanceofUnsupported" } ] } \ No newline at end of file diff --git a/linter-4.2/test/instanceof.ts.strict.json b/linter-4.2/test/instanceof.ts.strict.json index f9d548166..e63faa96a 100644 --- a/linter-4.2/test/instanceof.ts.strict.json +++ b/linter-4.2/test/instanceof.ts.strict.json @@ -33,6 +33,26 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" + }, + { + "line": 33, + "column": 18, + "problem": "InstanceofUnsupported" + }, + { + "line": 35, + "column": 14, + "problem": "InstanceofUnsupported" + }, + { + "line": 37, + "column": 19, + "problem": "InstanceofUnsupported" + }, + { + "line": 38, + "column": 19, + "problem": "InstanceofUnsupported" } ] } \ No newline at end of file diff --git a/linter/.gitignore b/linter/.gitignore index 3ded455fc..4797db793 100644 --- a/linter/.gitignore +++ b/linter/.gitignore @@ -2,6 +2,7 @@ build dist bundle node_modules +cookbook_convertor/md *.tsbuildinfo .vs .vscode diff --git a/linter/docs/rules/recipe1.md b/linter/docs/rules/recipe1.md index 317d04c6b..cda73e56f 100644 --- a/linter/docs/rules/recipe1.md +++ b/linter/docs/rules/recipe1.md @@ -27,7 +27,7 @@ data by numeric indices. ``` class X { - public name: number + public name: number = 0 } let x = {name: 1} console.log(x.name) diff --git a/linter/docs/rules/recipe118.md b/linter/docs/rules/recipe118.md index 0041552fd..f625bc3e9 100644 --- a/linter/docs/rules/recipe118.md +++ b/linter/docs/rules/recipe118.md @@ -14,10 +14,10 @@ Use ordinary import instead. ``` // Re-using the same import - import { APIResponseType } from "./api" + import { APIResponseType } from "api" // Explicitly use import type - import type { APIResponseType } from "./api" + import type { APIResponseType } from "api" ``` @@ -26,7 +26,7 @@ Use ordinary import instead. ``` - import { APIResponseType } from "./api" + import { APIResponseType } from "api" ``` diff --git a/linter/docs/rules/recipe128.md b/linter/docs/rules/recipe128.md index 9a5ccebd4..ddba6753b 100644 --- a/linter/docs/rules/recipe128.md +++ b/linter/docs/rules/recipe128.md @@ -25,7 +25,7 @@ own mechanisms for interoperating with JavaScript. ``` // Import what you need from the original module - import { normalize } from "../someModule" + import { normalize } from "someModule" ``` diff --git a/linter/docs/rules/recipe130.md b/linter/docs/rules/recipe130.md index da2aada01..4a5c602e6 100644 --- a/linter/docs/rules/recipe130.md +++ b/linter/docs/rules/recipe130.md @@ -35,7 +35,7 @@ import is a compile-time, not a runtime feature. Use ordinary syntax for } // in program - import { mathLib } from "./math-lib" + import { mathLib } from "math-lib" mathLib.isPrime(2) ``` diff --git a/linter/docs/rules/recipe131.md b/linter/docs/rules/recipe131.md index c9f6e9c22..a103967cd 100644 --- a/linter/docs/rules/recipe131.md +++ b/linter/docs/rules/recipe131.md @@ -13,7 +13,7 @@ has its own mechanisms for interoperating with JavaScript. ``` - import { something } from "./module.js" + import { something } from "module.js" ``` @@ -22,7 +22,7 @@ has its own mechanisms for interoperating with JavaScript. ``` - import { something } from "./module" + import { something } from "module" ``` diff --git a/linter/docs/rules/recipe133.md b/linter/docs/rules/recipe133.md index 222bfdee0..ab2f0a51e 100644 --- a/linter/docs/rules/recipe133.md +++ b/linter/docs/rules/recipe133.md @@ -14,7 +14,7 @@ import syntax instead. ``` - const zipUtil = await import("./utils/create-zip-file") + const zipUtil = await import("utils/create-zip-file") ``` @@ -23,7 +23,7 @@ import syntax instead. ``` - import { zipUtil } from "./utils/create-zip-file" + import { zipUtil } from "utils/create-zip-file" ``` diff --git a/linter/docs/rules/recipe135.md b/linter/docs/rules/recipe135.md index 545a49b9b..5e7bb8835 100644 --- a/linter/docs/rules/recipe135.md +++ b/linter/docs/rules/recipe135.md @@ -15,9 +15,10 @@ namespaces instead. ``` var C = (function() { - function C(n) { - this.p = n + function C(n: number) { + this.p = n // Compile-time error only with noImplicitThis } + C.staticProperty = 0 return C })() C.staticProperty = 1 diff --git a/linter/docs/rules/recipe136.md b/linter/docs/rules/recipe136.md index eb2ada706..550b95b54 100644 --- a/linter/docs/rules/recipe136.md +++ b/linter/docs/rules/recipe136.md @@ -15,7 +15,7 @@ applicable to the static typing. ``` var C = function(p) { - this.p = p + this.p = p // Compile-time error only with noImplicitThis } C.prototype = { diff --git a/linter/docs/rules/recipe137.md b/linter/docs/rules/recipe137.md index 588cc70f4..5cb8d691d 100644 --- a/linter/docs/rules/recipe137.md +++ b/linter/docs/rules/recipe137.md @@ -30,7 +30,7 @@ objects with dynamically changed layout are not supported. export let abc : number = 0 // file2 - import * as M from "../file1" + import * as M from "file1" M.abc = 200 diff --git a/linter/docs/rules/recipe138.md b/linter/docs/rules/recipe138.md index f97ec50ae..7dfec46f8 100644 --- a/linter/docs/rules/recipe138.md +++ b/linter/docs/rules/recipe138.md @@ -8,6 +8,9 @@ Currently ArkTS does not support utility types from TypeScript extensions to the standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``Record``. +For ``Record`` type, the type of value must be either optional or unioned with +the ``undefined`` type. + ## TypeScript @@ -22,6 +25,21 @@ standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, type QuantumPerson = Omit + let persons : Record = { + "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) // Runtime exception + ``` ## ArkTS @@ -30,14 +48,34 @@ standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``` class Person { - name: string - age: number - location: string + name: string = "" + age: number = 0 + location: string = "" } class QuantumPerson { - name: string - age: number + name: string = "" + age: number = 0 + } + + type OptionalPerson = Person | undefined + let persons : Record = { + // Or: + // let persons : Record = { + "Alice": { + name: "Alice", + age: 32, + location: "Shanghai" + }, + "Bob": { + name: "Bob", + age: 48, + location: "New York" + } + } + console.log(persons["Bob"]!.age) + if (persons["Rob"]) { // Explicit value check, no runtime exception + console.log(persons["Rob"].age) } ``` diff --git a/linter/docs/rules/recipe139.md b/linter/docs/rules/recipe139.md index 5b27d1ebf..70fd68966 100644 --- a/linter/docs/rules/recipe139.md +++ b/linter/docs/rules/recipe139.md @@ -49,15 +49,17 @@ this rule and their layout cannot be changed in runtime. // ... } - function readImage( + async function readImage( path: string, callback: (err: Error, image: MyImage) => void ) : Promise { - // async implementation + // In real world, the implementation is more complex, + // involving real network / DB logic, etc. + return await new MyImage() } function readImageSync(path: string) : MyImage { - // sync implementation + return new MyImage() } ``` diff --git a/linter/docs/rules/recipe142.md b/linter/docs/rules/recipe142.md index cca78dc76..7cef054e7 100644 --- a/linter/docs/rules/recipe142.md +++ b/linter/docs/rules/recipe142.md @@ -37,7 +37,7 @@ does not support literal types. let y : number[] = [10, 20] class Label { - text : string + text : string = "" } // Type 'Label': diff --git a/linter/docs/rules/recipe143.md b/linter/docs/rules/recipe143.md index 946b66efa..9dbec44af 100644 --- a/linter/docs/rules/recipe143.md +++ b/linter/docs/rules/recipe143.md @@ -15,7 +15,7 @@ in runtime does not make sense for the statically typed language. Use ordinary ``` - import { obj } from "./something.json" assert { type: "json" } + import { obj } from "something.json" assert { type: "json" } ``` @@ -25,7 +25,7 @@ in runtime does not make sense for the statically typed language. Use ordinary ``` // Correctness of importing T will be checked in compile-time: - import { something } from "./module" + import { something } from "module" ``` diff --git a/linter/docs/rules/recipe145.md b/linter/docs/rules/recipe145.md index 37e7be51f..26464d5d8 100644 --- a/linter/docs/rules/recipe145.md +++ b/linter/docs/rules/recipe145.md @@ -16,15 +16,21 @@ following flags should be turned on: ``noImplicitReturns``, ``` class C { - n: number - s: string + n: number // Compile-time error only with strictPropertyInitialization + s: string // Compile-time error only with strictPropertyInitialization } + // Compile-time error only with noImplicitReturns function foo(s: string): string { - console.log(s) + if (s != "") { + console.log(s) + return s + } else { + console.log(s) + } } - let n: number = null + let n: number = null // Compile-time error only with strictNullChecks ``` diff --git a/linter/docs/rules/recipe146.md b/linter/docs/rules/recipe146.md index f00a66b15..7ec5432f3 100644 --- a/linter/docs/rules/recipe146.md +++ b/linter/docs/rules/recipe146.md @@ -20,9 +20,10 @@ with special comments is not allowed. In particular, ``@ts-ignore`` and // Some code with switched off type checker // ... - // @ts-ignore let s1: string = null // No error, type checker suppressed - let s2: string = null // Compile-time error + + // @ts-ignore + let s2: string = null // No error, type checker suppressed ``` diff --git a/linter/docs/rules/recipe147.md b/linter/docs/rules/recipe147.md index 6a81f41c8..f3ca0e11f 100644 --- a/linter/docs/rules/recipe147.md +++ b/linter/docs/rules/recipe147.md @@ -20,8 +20,7 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" - + ``` - diff --git a/linter/docs/rules/recipe17.md b/linter/docs/rules/recipe17.md index 4dd591c0e..93066f260 100644 --- a/linter/docs/rules/recipe17.md +++ b/linter/docs/rules/recipe17.md @@ -32,7 +32,7 @@ ArkTS does not allow indexed signatures, use arrays instead. ``` class X { - public f: string[] + public f: string[] = [] } let myArray: X = new X() diff --git a/linter/docs/rules/recipe2.md b/linter/docs/rules/recipe2.md index 623cbff52..04a96f967 100644 --- a/linter/docs/rules/recipe2.md +++ b/linter/docs/rules/recipe2.md @@ -29,7 +29,7 @@ and cannot be changed at runtime. ``` class SomeClass { - public someProperty : string + public someProperty : string = "" } let o = new SomeClass() diff --git a/linter/docs/rules/recipe40.md b/linter/docs/rules/recipe40.md index 9fd22580f..dd4221b14 100644 --- a/linter/docs/rules/recipe40.md +++ b/linter/docs/rules/recipe40.md @@ -28,8 +28,8 @@ types in place. Declare classes and interfaces explicitly instead. ``` class O { - x: number - y: number + x: number = 0 + y: number = 0 } let o: O = {x: 2, y: 3} diff --git a/linter/docs/rules/recipe45.md b/linter/docs/rules/recipe45.md index 20680c932..70f14066e 100644 --- a/linter/docs/rules/recipe45.md +++ b/linter/docs/rules/recipe45.md @@ -13,7 +13,8 @@ to be explicitly specified. ``` - let f = (s) => { // type any is assumed + // Compile-time error only with noImplicitAny: + let f = (s /* type any is assumed */) => { console.log(s) } diff --git a/linter/docs/rules/recipe51.md b/linter/docs/rules/recipe51.md index 9b6ddc1fd..700a2409c 100644 --- a/linter/docs/rules/recipe51.md +++ b/linter/docs/rules/recipe51.md @@ -29,7 +29,7 @@ may be specified. ``` interface C { - foo() + foo(): void } class C1 implements C { diff --git a/linter/docs/rules/recipe52.md b/linter/docs/rules/recipe52.md index 91042ae77..f4ff3fd4b 100644 --- a/linter/docs/rules/recipe52.md +++ b/linter/docs/rules/recipe52.md @@ -19,7 +19,7 @@ existence during compilation. let n = person["name"] let e = person["isEmployee"] - let s = person["office"] // undefined + let s = person["office"] // Compile-time error only with noImplicitAny ``` diff --git a/linter/docs/rules/recipe59.md b/linter/docs/rules/recipe59.md index d64602e17..d2c937e46 100644 --- a/linter/docs/rules/recipe59.md +++ b/linter/docs/rules/recipe59.md @@ -32,8 +32,8 @@ changed at runtime. Thus the operation of deleting a property makes no sense. // and assign null to mark value absence: class Point { - x: number | null - y: number | null + x: number | null = 0 + y: number | null = 0 } let p = new Point() diff --git a/linter/docs/rules/recipe69.md b/linter/docs/rules/recipe69.md index 50d253b2f..80725b25c 100644 --- a/linter/docs/rules/recipe69.md +++ b/linter/docs/rules/recipe69.md @@ -34,11 +34,11 @@ using a temporary variable, where applicable) can be used for replacement. one = two two = tmp - let data: Number[] = [1,2,3,4] + let data: Number[] = [1, 2, 3, 4] let head = data[0] - let tail = new Number[data.length - 1] + let tail: Number[] = [] for (let i = 1; i < data.length; ++i) { - tail[i - 1] = data[i] + tail.push(data[i]) } ``` diff --git a/linter/docs/rules/recipe79.md b/linter/docs/rules/recipe79.md index 56ac1ea4f..15f916438 100644 --- a/linter/docs/rules/recipe79.md +++ b/linter/docs/rules/recipe79.md @@ -17,7 +17,9 @@ be omitted. try { // some code } - catch (a: unknown) {} + catch (a: unknown) { + // handle error + } ``` @@ -29,7 +31,9 @@ be omitted. try { // some code } - catch (a) {} + catch (a) { + // handle error + } ``` diff --git a/linter/docs/rules/recipe90.md b/linter/docs/rules/recipe90.md index 0613f6913..2ef93392a 100644 --- a/linter/docs/rules/recipe90.md +++ b/linter/docs/rules/recipe90.md @@ -16,6 +16,7 @@ explicitly. ``` + // Compile-time error with noImplicitAny function f(x: number) { if (x <= 0) { return x @@ -23,6 +24,7 @@ explicitly. return g(x) } + // Compile-time error with noImplicitAny function g(x: number) { return f(x - 1) } diff --git a/linter/docs/rules/recipe93.md b/linter/docs/rules/recipe93.md index ceb0cacf5..ab4bce316 100644 --- a/linter/docs/rules/recipe93.md +++ b/linter/docs/rules/recipe93.md @@ -14,7 +14,7 @@ ArkTS does not support the usage of ``this`` inside stand-alone functions. ``` function foo(i: number) { - this.count = i + this.count = i // Compile-time error only with noImplicitThis } class A { diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 7db9b171b..54c2c0681 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1428,6 +1428,12 @@ export class TypeScriptLinter { !this.tsUtils.relatedByInheritanceOrIdentical(targetType, exprType) ) this.incrementCounters(tsAsExpr, FaultID.StructuralIdentity); + // check for rule#65: 'number as Number' and 'boolean as Boolean' are disabled + if( + ( this.tsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' ) || + ( this.tsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) + ) + this.incrementCounters(node, FaultID.InstanceofUnsupported); } private handleTypeReference(node: ts.Node) { diff --git a/linter/test/instanceof.ts b/linter/test/instanceof.ts index 7f04b131b..2289a2292 100644 --- a/linter/test/instanceof.ts +++ b/linter/test/instanceof.ts @@ -28,3 +28,13 @@ const e = (5.0 as number) instanceof Number; // false const f = (X | String) instanceof Object; const g = 3 instanceof Number; + + +let bad2Number = 5.0 as Number; +let pi = 3.14; +bad2Number = pi as Number; + +let bad2Boolean = true as Boolean; +let bad2Boolean = a as Boolean; + + diff --git a/linter/test/instanceof.ts.relax.json b/linter/test/instanceof.ts.relax.json index f9d548166..e63faa96a 100644 --- a/linter/test/instanceof.ts.relax.json +++ b/linter/test/instanceof.ts.relax.json @@ -33,6 +33,26 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" + }, + { + "line": 33, + "column": 18, + "problem": "InstanceofUnsupported" + }, + { + "line": 35, + "column": 14, + "problem": "InstanceofUnsupported" + }, + { + "line": 37, + "column": 19, + "problem": "InstanceofUnsupported" + }, + { + "line": 38, + "column": 19, + "problem": "InstanceofUnsupported" } ] } \ No newline at end of file diff --git a/linter/test/instanceof.ts.strict.json b/linter/test/instanceof.ts.strict.json index f9d548166..e63faa96a 100644 --- a/linter/test/instanceof.ts.strict.json +++ b/linter/test/instanceof.ts.strict.json @@ -33,6 +33,26 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" + }, + { + "line": 33, + "column": 18, + "problem": "InstanceofUnsupported" + }, + { + "line": 35, + "column": 14, + "problem": "InstanceofUnsupported" + }, + { + "line": 37, + "column": 19, + "problem": "InstanceofUnsupported" + }, + { + "line": 38, + "column": 19, + "problem": "InstanceofUnsupported" } ] } \ No newline at end of file -- Gitee From 2fecc03dddd60b949dca81311b0dfdad4739db39 Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Fri, 4 Aug 2023 02:26:19 +0300 Subject: [PATCH 2/9] [TS Linter] update messages to CookBook version #227 Signed-off-by: Igor Rossinski --- linter-4.2/docs/rules/recipe115.md | 21 ------- linter-4.2/docs/rules/recipe145.md | 2 +- linter-4.2/docs/rules/recipe146.md | 2 +- linter-4.2/docs/rules/recipe147.md | 2 +- linter-4.2/docs/rules/recipe53.md | 15 +++++ linter-4.2/docs/rules/recipe55.md | 49 +++++++++++----- linter-4.2/docs/rules/recipe56.md | 54 ----------------- linter-4.2/docs/rules/recipe61.md | 71 ----------------------- linter-4.2/docs/rules/recipe63.md | 55 ------------------ linter-4.2/docs/rules/recipe65.md | 26 ++++----- linter-4.2/docs/rules/recipe8.md | 2 +- linter-4.2/src/CookBookMsg.ts | 10 ++-- linter-4.2/src/TypeScriptLinter.ts | 2 +- linter-4.2/test/instanceof.ts.relax.json | 20 ------- linter-4.2/test/instanceof.ts.strict.json | 8 +-- linter/docs/rules/recipe115.md | 21 ------- linter/docs/rules/recipe145.md | 2 +- linter/docs/rules/recipe146.md | 2 +- linter/docs/rules/recipe147.md | 2 +- linter/docs/rules/recipe53.md | 15 +++++ linter/docs/rules/recipe55.md | 49 +++++++++++----- linter/docs/rules/recipe56.md | 54 ----------------- linter/docs/rules/recipe61.md | 71 ----------------------- linter/docs/rules/recipe63.md | 55 ------------------ linter/docs/rules/recipe65.md | 26 ++++----- linter/docs/rules/recipe8.md | 2 +- linter/src/CookBookMsg.ts | 10 ++-- linter/src/TypeScriptLinter.ts | 2 +- linter/test/instanceof.ts.relax.json | 20 ------- linter/test/instanceof.ts.strict.json | 8 +-- 30 files changed, 148 insertions(+), 530 deletions(-) delete mode 100644 linter-4.2/docs/rules/recipe115.md delete mode 100644 linter-4.2/docs/rules/recipe56.md delete mode 100644 linter-4.2/docs/rules/recipe61.md delete mode 100644 linter-4.2/docs/rules/recipe63.md delete mode 100644 linter/docs/rules/recipe115.md delete mode 100644 linter/docs/rules/recipe56.md delete mode 100644 linter/docs/rules/recipe61.md delete mode 100644 linter/docs/rules/recipe63.md diff --git a/linter-4.2/docs/rules/recipe115.md b/linter-4.2/docs/rules/recipe115.md deleted file mode 100644 index ee73f68fd..000000000 --- a/linter-4.2/docs/rules/recipe115.md +++ /dev/null @@ -1,21 +0,0 @@ -# Scripts and modules - -Rule ``arkts-no-scripts`` - -**Severity: error** - -In general, scripts and modules in ArkTS are very close to TypeScript. -Differences are described in separate recipes. - - -## See also - -- Recipe 118: Special import type declarations are not supported (``arkts-no-special-imports``) -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter-4.2/docs/rules/recipe145.md b/linter-4.2/docs/rules/recipe145.md index 26464d5d8..022f436ff 100644 --- a/linter-4.2/docs/rules/recipe145.md +++ b/linter-4.2/docs/rules/recipe145.md @@ -56,7 +56,7 @@ following flags should be turned on: ``noImplicitReturns``, ## See also -- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-undefined-unknown``) +- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-unknown``) - Recipe 146: Switching off type checks with in-place comments is not allowed (``arkts-strict-typing-required``) diff --git a/linter-4.2/docs/rules/recipe146.md b/linter-4.2/docs/rules/recipe146.md index 7ec5432f3..6426faf28 100644 --- a/linter-4.2/docs/rules/recipe146.md +++ b/linter-4.2/docs/rules/recipe146.md @@ -39,7 +39,7 @@ with special comments is not allowed. In particular, ``@ts-ignore`` and ## See also -- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-undefined-unknown``) +- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-unknown``) - Recipe 145: Strict type checking is enforced (``arkts-strict-typing``) diff --git a/linter-4.2/docs/rules/recipe147.md b/linter-4.2/docs/rules/recipe147.md index f3ca0e11f..de1f456d1 100644 --- a/linter-4.2/docs/rules/recipe147.md +++ b/linter-4.2/docs/rules/recipe147.md @@ -20,7 +20,7 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" - + ``` diff --git a/linter-4.2/docs/rules/recipe53.md b/linter-4.2/docs/rules/recipe53.md index 17c22a056..ea6c5a8a1 100644 --- a/linter-4.2/docs/rules/recipe53.md +++ b/linter-4.2/docs/rules/recipe53.md @@ -8,6 +8,10 @@ ArkTS supports ``as`` keyword as the only syntax for type casts. Incorrect cast causes a compile-time error or runtime ``ClassCastException``. ```` syntax for type casts is not supported. +However, if a **primitive** type (e.g. a ``number`` or a ``boolean``) must be +cast to the reference type, this must be done through the ``new ...`` expression +instead of ``as``. + ## TypeScript @@ -31,6 +35,14 @@ Incorrect cast causes a compile-time error or runtime ``ClassCastException``. let c3 = createShape() as Square console.log(c3.y) // undefined + // Important corner case for casting primitives to the boxed counterparts: + // The left operand is not properly boxed here in in runtime + // because "as" has no runtime effect in TypeScript + let e1 = (5.0 as Number) instanceof Number // false + + // Number object is created and instanceof works as expected: + let e2 = (new Number(5.0)) instanceof Number // true + ``` ## ArkTS @@ -51,6 +63,9 @@ Incorrect cast causes a compile-time error or runtime ``ClassCastException``. // ClassCastException during runtime is thrown: let c3 = createShape() as Square + // Number object is created and instanceof works as expected: + let e2 = (new Number(5.0)) instanceof Number // true + ``` diff --git a/linter-4.2/docs/rules/recipe55.md b/linter-4.2/docs/rules/recipe55.md index 2b47bb525..42eb50236 100644 --- a/linter-4.2/docs/rules/recipe55.md +++ b/linter-4.2/docs/rules/recipe55.md @@ -15,14 +15,25 @@ be done explicitly. ``` - 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 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 @@ -30,19 +41,25 @@ be done explicitly. ``` - 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 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" + } -## See also + let x = +returnTen() // Compile-time error + let y = +returnString() // Compile-time error -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) +``` diff --git a/linter-4.2/docs/rules/recipe56.md b/linter-4.2/docs/rules/recipe56.md deleted file mode 100644 index 8f1cb613e..000000000 --- a/linter-4.2/docs/rules/recipe56.md +++ /dev/null @@ -1,54 +0,0 @@ -# Unary ``+`` cannot be used for casting to ``number`` - -Rule ``arkts-no-unary-plus-cast`` - -**Severity: error** - -ArkTS does not support casting from any type to a numeric type -by using the unary ``+`` operator, which can be applied only to -numeric types. - - -## TypeScript - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // -10 as number - let b = +returnString() // NaN - -``` - -## ArkTS - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // Compile-time error - let b = +returnString() // Compile-time error - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter-4.2/docs/rules/recipe61.md b/linter-4.2/docs/rules/recipe61.md deleted file mode 100644 index e5bdfd14a..000000000 --- a/linter-4.2/docs/rules/recipe61.md +++ /dev/null @@ -1,71 +0,0 @@ -# Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types - -Rule ``arkts-no-polymorphic-binops`` - -**Severity: error** - -ArkTS allows applying binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, -``>>``, ``>>>``, ``&``, ``^`` and ``|`` only to values of numeric types. -Implicit casts from other types to numeric types are prohibited and cause -compile-time errors. - - -## TypeScript - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // 5, not 5.5 - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // 5, not 5.5 - - enum Direction { - Up = -1, - Down - } - let e = Direction.Up >> 1 // -1 - let f = Direction.Up >>> 1 // 2147483647 - - let g = ("10" as any) << 1 // 20 - let h = ("str" as any) << 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## ArkTS - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // Compile-time error - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // Compile-time error - - enum Direction { - Up, - Down - } - - let e = Direction.Up >> 1 // 0 - let f = Direction.Up >>> 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter-4.2/docs/rules/recipe63.md b/linter-4.2/docs/rules/recipe63.md deleted file mode 100644 index 47b26ae72..000000000 --- a/linter-4.2/docs/rules/recipe63.md +++ /dev/null @@ -1,55 +0,0 @@ -# Binary ``+`` operator supports implicit casts only for numbers and strings - -Rule ``arkts-no-polymorphic-plus`` - -**Severity: error** - -ArkTS supports implicit casts for ``+`` only for strings and numbers. -Elsewhere, any form of an explicit cast to string is required. - - -## TypeScript - - -``` - - enum E { E1, E2 } - - let a = 10 + 32 // 42 - let b = E.E1 + 10 // 10 - let c = 10 + "5" // "105" - - let d = "5" + E.E2 // "51" - let e = "Hello, " + "world!" // "Hello, world!" - let f = "string" + true // "stringtrue" - - let g = (new Object()) + "string" // "[object Object]string" - -``` - -## ArkTS - - -``` - - enum E { E1, E2 } - - let a = 10 + 32 // 42 - let b = E.E1 + 10 // 10 - let c = 10 + "5" // "105" - - let d = "5" + E.E2 // "51" - let e = "Hello, " + "world!" // "Hello, world!" - let f = "string" + true // "stringtrue" - - let g = (new Object()).toString() + "string" - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) - - diff --git a/linter-4.2/docs/rules/recipe65.md b/linter-4.2/docs/rules/recipe65.md index b72b699c3..89e956fcb 100644 --- a/linter-4.2/docs/rules/recipe65.md +++ b/linter-4.2/docs/rules/recipe65.md @@ -16,16 +16,15 @@ a type. ``` - class X {} + class X { + // ... + } let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // true - let d = X instanceof X // false + let b = (new X()) instanceof X // true - // left operand is not of type any - let e = (5.0 as Number) instanceof Number // false + let c = X instanceof Object // true, left operand is a type + let d = X instanceof X // false, left operand is a type ``` @@ -34,16 +33,15 @@ a type. ``` - class X {} + class X { + // ... + } let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // Compile-time error - let d = X instanceof X // Compile-time error + let b = (new X()) instanceof X // true - // left operand may be of any reference type, like number - let e = (5.0 as Number) instanceof Number // true + let c = X instanceof Object // Compile-time error, left operand is a type + let d = X instanceof X // Compile-time error, left operand is a type ``` diff --git a/linter-4.2/docs/rules/recipe8.md b/linter-4.2/docs/rules/recipe8.md index fd3e9e100..327672363 100644 --- a/linter-4.2/docs/rules/recipe8.md +++ b/linter-4.2/docs/rules/recipe8.md @@ -1,6 +1,6 @@ # Use explicit types instead of ``any``, ``unknown`` -Rule ``arkts-no-any-undefined-unknown`` +Rule ``arkts-no-any-unknown`` **Severity: error** diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index 57e28c882..50cf78a1b 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -27,7 +27,7 @@ cookBookTag[ 4 ] = 'Use unique names for types, namespaces, etc. (arkts-unique-n cookBookTag[ 5 ] = 'Use "let" instead of "var" (arkts-no-var)'; cookBookTag[ 6 ] = ''; cookBookTag[ 7 ] = ''; -cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-undefined-unknown)'; +cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)'; cookBookTag[ 9 ] = ''; cookBookTag[ 10 ] = '"bigint" is not a builtin type, suffix "n" for numeric literals is not supported (arkts-no-n-suffix)'; cookBookTag[ 11 ] = ''; @@ -75,14 +75,14 @@ cookBookTag[ 52 ] = 'Attempt to access an undefined property is a compile-time e cookBookTag[ 53 ] = 'Only "as T" syntax is supported for type casts (arkts-as-casts)'; cookBookTag[ 54 ] = 'JSX expressions are not supported (arkts-no-jsx)'; cookBookTag[ 55 ] = 'Unary operators "+", "-" and "~" work only on numbers (arkts-no-polymorphic-unops)'; -cookBookTag[ 56 ] = 'Unary "+" cannot be used for casting to "number" (arkts-no-unary-plus-cast)'; +cookBookTag[ 56 ] = ''; cookBookTag[ 57 ] = ''; cookBookTag[ 58 ] = ''; cookBookTag[ 59 ] = '"delete" operator is not supported (arkts-no-delete)'; cookBookTag[ 60 ] = '"typeof" operator is allowed only in expression contexts (arkts-no-type-query)'; -cookBookTag[ 61 ] = 'Binary operators "*", "/", "%", "-", "<<", ">>", ">>>", "&", "^" and "|" work only on numeric types (arkts-no-polymorphic-binops)'; +cookBookTag[ 61 ] = ''; cookBookTag[ 62 ] = ''; -cookBookTag[ 63 ] = 'Binary "+" operator supports implicit casts only for numbers and strings (arkts-no-polymorphic-plus)'; +cookBookTag[ 63 ] = ''; cookBookTag[ 64 ] = ''; cookBookTag[ 65 ] = '"instanceof" operator is partially supported (arkts-instanceof-ref-types)'; cookBookTag[ 66 ] = '"in" operator is not supported (arkts-no-in)'; @@ -134,7 +134,7 @@ cookBookTag[ 111 ] = 'Enumeration members can be initialized only with compile t cookBookTag[ 112 ] = ''; cookBookTag[ 113 ] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[ 114 ] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; -cookBookTag[ 115 ] = 'Scripts and modules (arkts-no-scripts)'; +cookBookTag[ 115 ] = ''; cookBookTag[ 116 ] = 'Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)'; cookBookTag[ 117 ] = ''; cookBookTag[ 118 ] = 'Special import type declarations are not supported (arkts-no-special-imports)'; diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index aad8f7d46..8afdf97da 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -1407,7 +1407,7 @@ export class TypeScriptLinter { ( Utils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' ) || ( Utils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) ) - this.incrementCounters(node, FaultID.InstanceofUnsupported); + this.incrementCounters(node, FaultID.TypeAssertion); } private handleTypeReference(node: ts.Node) { diff --git a/linter-4.2/test/instanceof.ts.relax.json b/linter-4.2/test/instanceof.ts.relax.json index e63faa96a..f9d548166 100644 --- a/linter-4.2/test/instanceof.ts.relax.json +++ b/linter-4.2/test/instanceof.ts.relax.json @@ -33,26 +33,6 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" - }, - { - "line": 33, - "column": 18, - "problem": "InstanceofUnsupported" - }, - { - "line": 35, - "column": 14, - "problem": "InstanceofUnsupported" - }, - { - "line": 37, - "column": 19, - "problem": "InstanceofUnsupported" - }, - { - "line": 38, - "column": 19, - "problem": "InstanceofUnsupported" } ] } \ No newline at end of file diff --git a/linter-4.2/test/instanceof.ts.strict.json b/linter-4.2/test/instanceof.ts.strict.json index e63faa96a..d95a4cf33 100644 --- a/linter-4.2/test/instanceof.ts.strict.json +++ b/linter-4.2/test/instanceof.ts.strict.json @@ -37,22 +37,22 @@ { "line": 33, "column": 18, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 35, "column": 14, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 37, "column": 19, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 38, "column": 19, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" } ] } \ No newline at end of file diff --git a/linter/docs/rules/recipe115.md b/linter/docs/rules/recipe115.md deleted file mode 100644 index ee73f68fd..000000000 --- a/linter/docs/rules/recipe115.md +++ /dev/null @@ -1,21 +0,0 @@ -# Scripts and modules - -Rule ``arkts-no-scripts`` - -**Severity: error** - -In general, scripts and modules in ArkTS are very close to TypeScript. -Differences are described in separate recipes. - - -## See also - -- Recipe 118: Special import type declarations are not supported (``arkts-no-special-imports``) -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter/docs/rules/recipe145.md b/linter/docs/rules/recipe145.md index 26464d5d8..022f436ff 100644 --- a/linter/docs/rules/recipe145.md +++ b/linter/docs/rules/recipe145.md @@ -56,7 +56,7 @@ following flags should be turned on: ``noImplicitReturns``, ## See also -- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-undefined-unknown``) +- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-unknown``) - Recipe 146: Switching off type checks with in-place comments is not allowed (``arkts-strict-typing-required``) diff --git a/linter/docs/rules/recipe146.md b/linter/docs/rules/recipe146.md index 7ec5432f3..6426faf28 100644 --- a/linter/docs/rules/recipe146.md +++ b/linter/docs/rules/recipe146.md @@ -39,7 +39,7 @@ with special comments is not allowed. In particular, ``@ts-ignore`` and ## See also -- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-undefined-unknown``) +- Recipe 008: Use explicit types instead of ``any``, ``unknown`` (``arkts-no-any-unknown``) - Recipe 145: Strict type checking is enforced (``arkts-strict-typing``) diff --git a/linter/docs/rules/recipe147.md b/linter/docs/rules/recipe147.md index f3ca0e11f..de1f456d1 100644 --- a/linter/docs/rules/recipe147.md +++ b/linter/docs/rules/recipe147.md @@ -20,7 +20,7 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" - + ``` diff --git a/linter/docs/rules/recipe53.md b/linter/docs/rules/recipe53.md index 17c22a056..ea6c5a8a1 100644 --- a/linter/docs/rules/recipe53.md +++ b/linter/docs/rules/recipe53.md @@ -8,6 +8,10 @@ ArkTS supports ``as`` keyword as the only syntax for type casts. Incorrect cast causes a compile-time error or runtime ``ClassCastException``. ```` syntax for type casts is not supported. +However, if a **primitive** type (e.g. a ``number`` or a ``boolean``) must be +cast to the reference type, this must be done through the ``new ...`` expression +instead of ``as``. + ## TypeScript @@ -31,6 +35,14 @@ Incorrect cast causes a compile-time error or runtime ``ClassCastException``. let c3 = createShape() as Square console.log(c3.y) // undefined + // Important corner case for casting primitives to the boxed counterparts: + // The left operand is not properly boxed here in in runtime + // because "as" has no runtime effect in TypeScript + let e1 = (5.0 as Number) instanceof Number // false + + // Number object is created and instanceof works as expected: + let e2 = (new Number(5.0)) instanceof Number // true + ``` ## ArkTS @@ -51,6 +63,9 @@ Incorrect cast causes a compile-time error or runtime ``ClassCastException``. // ClassCastException during runtime is thrown: let c3 = createShape() as Square + // Number object is created and instanceof works as expected: + let e2 = (new Number(5.0)) instanceof Number // true + ``` diff --git a/linter/docs/rules/recipe55.md b/linter/docs/rules/recipe55.md index 2b47bb525..42eb50236 100644 --- a/linter/docs/rules/recipe55.md +++ b/linter/docs/rules/recipe55.md @@ -15,14 +15,25 @@ be done explicitly. ``` - 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 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 @@ -30,19 +41,25 @@ be done explicitly. ``` - 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 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" + } -## See also + let x = +returnTen() // Compile-time error + let y = +returnString() // Compile-time error -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) +``` diff --git a/linter/docs/rules/recipe56.md b/linter/docs/rules/recipe56.md deleted file mode 100644 index 8f1cb613e..000000000 --- a/linter/docs/rules/recipe56.md +++ /dev/null @@ -1,54 +0,0 @@ -# Unary ``+`` cannot be used for casting to ``number`` - -Rule ``arkts-no-unary-plus-cast`` - -**Severity: error** - -ArkTS does not support casting from any type to a numeric type -by using the unary ``+`` operator, which can be applied only to -numeric types. - - -## TypeScript - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // -10 as number - let b = +returnString() // NaN - -``` - -## ArkTS - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // Compile-time error - let b = +returnString() // Compile-time error - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter/docs/rules/recipe61.md b/linter/docs/rules/recipe61.md deleted file mode 100644 index e5bdfd14a..000000000 --- a/linter/docs/rules/recipe61.md +++ /dev/null @@ -1,71 +0,0 @@ -# Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types - -Rule ``arkts-no-polymorphic-binops`` - -**Severity: error** - -ArkTS allows applying binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, -``>>``, ``>>>``, ``&``, ``^`` and ``|`` only to values of numeric types. -Implicit casts from other types to numeric types are prohibited and cause -compile-time errors. - - -## TypeScript - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // 5, not 5.5 - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // 5, not 5.5 - - enum Direction { - Up = -1, - Down - } - let e = Direction.Up >> 1 // -1 - let f = Direction.Up >>> 1 // 2147483647 - - let g = ("10" as any) << 1 // 20 - let h = ("str" as any) << 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## ArkTS - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // Compile-time error - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // Compile-time error - - enum Direction { - Up, - Down - } - - let e = Direction.Up >> 1 // 0 - let f = Direction.Up >>> 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter/docs/rules/recipe63.md b/linter/docs/rules/recipe63.md deleted file mode 100644 index 47b26ae72..000000000 --- a/linter/docs/rules/recipe63.md +++ /dev/null @@ -1,55 +0,0 @@ -# Binary ``+`` operator supports implicit casts only for numbers and strings - -Rule ``arkts-no-polymorphic-plus`` - -**Severity: error** - -ArkTS supports implicit casts for ``+`` only for strings and numbers. -Elsewhere, any form of an explicit cast to string is required. - - -## TypeScript - - -``` - - enum E { E1, E2 } - - let a = 10 + 32 // 42 - let b = E.E1 + 10 // 10 - let c = 10 + "5" // "105" - - let d = "5" + E.E2 // "51" - let e = "Hello, " + "world!" // "Hello, world!" - let f = "string" + true // "stringtrue" - - let g = (new Object()) + "string" // "[object Object]string" - -``` - -## ArkTS - - -``` - - enum E { E1, E2 } - - let a = 10 + 32 // 42 - let b = E.E1 + 10 // 10 - let c = 10 + "5" // "105" - - let d = "5" + E.E2 // "51" - let e = "Hello, " + "world!" // "Hello, world!" - let f = "string" + true // "stringtrue" - - let g = (new Object()).toString() + "string" - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) - - diff --git a/linter/docs/rules/recipe65.md b/linter/docs/rules/recipe65.md index b72b699c3..89e956fcb 100644 --- a/linter/docs/rules/recipe65.md +++ b/linter/docs/rules/recipe65.md @@ -16,16 +16,15 @@ a type. ``` - class X {} + class X { + // ... + } let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // true - let d = X instanceof X // false + let b = (new X()) instanceof X // true - // left operand is not of type any - let e = (5.0 as Number) instanceof Number // false + let c = X instanceof Object // true, left operand is a type + let d = X instanceof X // false, left operand is a type ``` @@ -34,16 +33,15 @@ a type. ``` - class X {} + class X { + // ... + } let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // Compile-time error - let d = X instanceof X // Compile-time error + let b = (new X()) instanceof X // true - // left operand may be of any reference type, like number - let e = (5.0 as Number) instanceof Number // true + let c = X instanceof Object // Compile-time error, left operand is a type + let d = X instanceof X // Compile-time error, left operand is a type ``` diff --git a/linter/docs/rules/recipe8.md b/linter/docs/rules/recipe8.md index fd3e9e100..327672363 100644 --- a/linter/docs/rules/recipe8.md +++ b/linter/docs/rules/recipe8.md @@ -1,6 +1,6 @@ # Use explicit types instead of ``any``, ``unknown`` -Rule ``arkts-no-any-undefined-unknown`` +Rule ``arkts-no-any-unknown`` **Severity: error** diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index 57e28c882..50cf78a1b 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -27,7 +27,7 @@ cookBookTag[ 4 ] = 'Use unique names for types, namespaces, etc. (arkts-unique-n cookBookTag[ 5 ] = 'Use "let" instead of "var" (arkts-no-var)'; cookBookTag[ 6 ] = ''; cookBookTag[ 7 ] = ''; -cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-undefined-unknown)'; +cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)'; cookBookTag[ 9 ] = ''; cookBookTag[ 10 ] = '"bigint" is not a builtin type, suffix "n" for numeric literals is not supported (arkts-no-n-suffix)'; cookBookTag[ 11 ] = ''; @@ -75,14 +75,14 @@ cookBookTag[ 52 ] = 'Attempt to access an undefined property is a compile-time e cookBookTag[ 53 ] = 'Only "as T" syntax is supported for type casts (arkts-as-casts)'; cookBookTag[ 54 ] = 'JSX expressions are not supported (arkts-no-jsx)'; cookBookTag[ 55 ] = 'Unary operators "+", "-" and "~" work only on numbers (arkts-no-polymorphic-unops)'; -cookBookTag[ 56 ] = 'Unary "+" cannot be used for casting to "number" (arkts-no-unary-plus-cast)'; +cookBookTag[ 56 ] = ''; cookBookTag[ 57 ] = ''; cookBookTag[ 58 ] = ''; cookBookTag[ 59 ] = '"delete" operator is not supported (arkts-no-delete)'; cookBookTag[ 60 ] = '"typeof" operator is allowed only in expression contexts (arkts-no-type-query)'; -cookBookTag[ 61 ] = 'Binary operators "*", "/", "%", "-", "<<", ">>", ">>>", "&", "^" and "|" work only on numeric types (arkts-no-polymorphic-binops)'; +cookBookTag[ 61 ] = ''; cookBookTag[ 62 ] = ''; -cookBookTag[ 63 ] = 'Binary "+" operator supports implicit casts only for numbers and strings (arkts-no-polymorphic-plus)'; +cookBookTag[ 63 ] = ''; cookBookTag[ 64 ] = ''; cookBookTag[ 65 ] = '"instanceof" operator is partially supported (arkts-instanceof-ref-types)'; cookBookTag[ 66 ] = '"in" operator is not supported (arkts-no-in)'; @@ -134,7 +134,7 @@ cookBookTag[ 111 ] = 'Enumeration members can be initialized only with compile t cookBookTag[ 112 ] = ''; cookBookTag[ 113 ] = '"enum" declaration merging is not supported (arkts-no-enum-merging)'; cookBookTag[ 114 ] = 'Namespaces cannot be used as objects (arkts-no-ns-as-obj)'; -cookBookTag[ 115 ] = 'Scripts and modules (arkts-no-scripts)'; +cookBookTag[ 115 ] = ''; cookBookTag[ 116 ] = 'Non-declaration statements in namespaces are not supported (arkts-no-ns-statements)'; cookBookTag[ 117 ] = ''; cookBookTag[ 118 ] = 'Special import type declarations are not supported (arkts-no-special-imports)'; diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index 54c2c0681..bfc3b80dc 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1433,7 +1433,7 @@ export class TypeScriptLinter { ( this.tsUtils.isNumberType(exprType) && targetType.getSymbol()?.getName() === 'Number' ) || ( this.tsUtils.isBooleanType(exprType) && targetType.getSymbol()?.getName() === 'Boolean' ) ) - this.incrementCounters(node, FaultID.InstanceofUnsupported); + this.incrementCounters(node, FaultID.TypeAssertion); } private handleTypeReference(node: ts.Node) { diff --git a/linter/test/instanceof.ts.relax.json b/linter/test/instanceof.ts.relax.json index e63faa96a..f9d548166 100644 --- a/linter/test/instanceof.ts.relax.json +++ b/linter/test/instanceof.ts.relax.json @@ -33,26 +33,6 @@ "line": 30, "column": 11, "problem": "InstanceofUnsupported" - }, - { - "line": 33, - "column": 18, - "problem": "InstanceofUnsupported" - }, - { - "line": 35, - "column": 14, - "problem": "InstanceofUnsupported" - }, - { - "line": 37, - "column": 19, - "problem": "InstanceofUnsupported" - }, - { - "line": 38, - "column": 19, - "problem": "InstanceofUnsupported" } ] } \ No newline at end of file diff --git a/linter/test/instanceof.ts.strict.json b/linter/test/instanceof.ts.strict.json index e63faa96a..d95a4cf33 100644 --- a/linter/test/instanceof.ts.strict.json +++ b/linter/test/instanceof.ts.strict.json @@ -37,22 +37,22 @@ { "line": 33, "column": 18, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 35, "column": 14, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 37, "column": 19, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" }, { "line": 38, "column": 19, - "problem": "InstanceofUnsupported" + "problem": "TypeAssertion" } ] } \ No newline at end of file -- Gitee From cbca5eef5b9f7e362ca997e55b3336f7dd8b5ae8 Mon Sep 17 00:00:00 2001 From: Igor Rossinski Date: Fri, 4 Aug 2023 21:20:46 +0300 Subject: [PATCH 3/9] [TS Linter] fix #13005 and update to spec201 Signed-off-by: Igor Rossinski --- .../src/cookbook_convertor.ts | 4 +- linter-4.2/docs/rules/recipe10.md | 31 ---- linter-4.2/docs/rules/recipe102.md | 4 +- linter-4.2/docs/rules/recipe105.md | 7 +- linter-4.2/docs/rules/recipe109.md | 8 +- linter-4.2/docs/rules/recipe113.md | 4 +- linter-4.2/docs/rules/recipe121.md | 6 +- linter-4.2/docs/rules/recipe124.md | 39 ----- linter-4.2/docs/rules/recipe125.md | 1 - linter-4.2/docs/rules/recipe126.md | 1 - linter-4.2/docs/rules/recipe129.md | 25 ++- linter-4.2/docs/rules/recipe130.md | 8 +- linter-4.2/docs/rules/recipe131.md | 4 +- linter-4.2/docs/rules/recipe132.md | 17 ++ linter-4.2/docs/rules/recipe133.md | 4 +- linter-4.2/docs/rules/recipe134.md | 4 +- linter-4.2/docs/rules/recipe135.md | 6 +- linter-4.2/docs/rules/recipe136.md | 26 +++- linter-4.2/docs/rules/recipe138.md | 4 +- linter-4.2/docs/rules/recipe140.md | 10 +- linter-4.2/docs/rules/recipe141.md | 2 +- linter-4.2/docs/rules/recipe143.md | 2 +- linter-4.2/docs/rules/recipe144.md | 8 +- linter-4.2/docs/rules/recipe145.md | 2 +- linter-4.2/docs/rules/recipe146.md | 2 +- linter-4.2/docs/rules/recipe147.md | 22 ++- linter-4.2/docs/rules/recipe148.md | 42 +++++ linter-4.2/docs/rules/recipe16.md | 4 +- linter-4.2/docs/rules/recipe19.md | 4 +- linter-4.2/docs/rules/recipe22.md | 4 +- linter-4.2/docs/rules/recipe25.md | 2 +- linter-4.2/docs/rules/recipe27.md | 2 +- linter-4.2/docs/rules/recipe3.md | 4 +- linter-4.2/docs/rules/recipe30.md | 2 +- linter-4.2/docs/rules/recipe31.md | 2 +- linter-4.2/docs/rules/recipe32.md | 4 +- linter-4.2/docs/rules/recipe34.md | 4 +- linter-4.2/docs/rules/recipe35.md | 2 +- linter-4.2/docs/rules/recipe37.md | 4 +- linter-4.2/docs/rules/recipe38.md | 6 +- linter-4.2/docs/rules/recipe43.md | 4 +- linter-4.2/docs/rules/recipe46.md | 4 +- linter-4.2/docs/rules/recipe50.md | 4 +- linter-4.2/docs/rules/recipe52.md | 2 +- linter-4.2/docs/rules/recipe53.md | 7 +- linter-4.2/docs/rules/recipe60.md | 4 +- .../md => linter-4.2/docs/rules}/recipe63.md | 25 ++- linter-4.2/docs/rules/recipe66.md | 2 +- linter-4.2/docs/rules/recipe76.md | 6 +- linter-4.2/docs/rules/recipe79.md | 4 +- linter-4.2/docs/rules/recipe8.md | 4 +- linter-4.2/docs/rules/recipe80.md | 7 +- linter-4.2/docs/rules/recipe81.md | 2 +- linter-4.2/docs/rules/recipe82.md | 2 +- linter-4.2/docs/rules/recipe84.md | 22 +++ linter-4.2/docs/rules/recipe99.md | 2 +- linter-4.2/src/CookBookMsg.ts | 15 +- linter-4.2/src/Problems.ts | 4 +- linter-4.2/src/TypeScriptLinter.ts | 12 +- linter-4.2/src/TypeScriptLinterConfig.ts | 2 +- linter-4.2/src/Utils.ts | 6 + linter-4.2/test/binary_wrong_types.ts | 9 ++ .../test/binary_wrong_types.ts.relax.json | 122 +-------------- .../test/binary_wrong_types.ts.strict.json | 122 +-------------- linter-4.2/test/instanceof.ts.relax.json | 5 - linter-4.2/test/instanceof.ts.strict.json | 5 - linter/cookbook_convertor/md/recipe1.md | 59 ------- linter/cookbook_convertor/md/recipe10.md | 31 ---- linter/cookbook_convertor/md/recipe102.md | 105 ------------- linter/cookbook_convertor/md/recipe103.md | 47 ------ linter/cookbook_convertor/md/recipe104.md | 41 ----- linter/cookbook_convertor/md/recipe105.md | 73 --------- linter/cookbook_convertor/md/recipe106.md | 60 ------- linter/cookbook_convertor/md/recipe109.md | 69 --------- linter/cookbook_convertor/md/recipe111.md | 56 ------- linter/cookbook_convertor/md/recipe113.md | 45 ------ linter/cookbook_convertor/md/recipe114.md | 38 ----- linter/cookbook_convertor/md/recipe115.md | 21 --- linter/cookbook_convertor/md/recipe116.md | 41 ----- linter/cookbook_convertor/md/recipe118.md | 39 ----- linter/cookbook_convertor/md/recipe119.md | 37 ----- linter/cookbook_convertor/md/recipe120.md | 29 ---- linter/cookbook_convertor/md/recipe121.md | 28 ---- linter/cookbook_convertor/md/recipe124.md | 39 ----- linter/cookbook_convertor/md/recipe125.md | 57 ------- linter/cookbook_convertor/md/recipe126.md | 54 ------- linter/cookbook_convertor/md/recipe127.md | 30 ---- linter/cookbook_convertor/md/recipe128.md | 37 ----- linter/cookbook_convertor/md/recipe129.md | 29 ---- linter/cookbook_convertor/md/recipe13.md | 33 ---- linter/cookbook_convertor/md/recipe130.md | 47 ------ linter/cookbook_convertor/md/recipe131.md | 34 ---- linter/cookbook_convertor/md/recipe132.md | 33 ---- linter/cookbook_convertor/md/recipe133.md | 36 ----- linter/cookbook_convertor/md/recipe134.md | 44 ------ linter/cookbook_convertor/md/recipe135.md | 38 ----- linter/cookbook_convertor/md/recipe136.md | 37 ----- linter/cookbook_convertor/md/recipe137.md | 44 ------ linter/cookbook_convertor/md/recipe138.md | 45 ------ linter/cookbook_convertor/md/recipe139.md | 69 --------- linter/cookbook_convertor/md/recipe14.md | 53 ------- linter/cookbook_convertor/md/recipe140.md | 65 -------- linter/cookbook_convertor/md/recipe141.md | 34 ---- linter/cookbook_convertor/md/recipe142.md | 50 ------ linter/cookbook_convertor/md/recipe143.md | 38 ----- linter/cookbook_convertor/md/recipe144.md | 54 ------- linter/cookbook_convertor/md/recipe15.md | 50 ------ linter/cookbook_convertor/md/recipe16.md | 47 ------ linter/cookbook_convertor/md/recipe17.md | 43 ------ linter/cookbook_convertor/md/recipe19.md | 49 ------ linter/cookbook_convertor/md/recipe2.md | 49 ------ linter/cookbook_convertor/md/recipe21.md | 32 ---- linter/cookbook_convertor/md/recipe22.md | 40 ----- linter/cookbook_convertor/md/recipe25.md | 57 ------- linter/cookbook_convertor/md/recipe27.md | 44 ------ linter/cookbook_convertor/md/recipe28.md | 30 ---- linter/cookbook_convertor/md/recipe29.md | 33 ---- linter/cookbook_convertor/md/recipe3.md | 34 ---- linter/cookbook_convertor/md/recipe30.md | 51 ------ linter/cookbook_convertor/md/recipe31.md | 84 ---------- linter/cookbook_convertor/md/recipe32.md | 88 ----------- linter/cookbook_convertor/md/recipe34.md | 51 ------ linter/cookbook_convertor/md/recipe35.md | 103 ------------ linter/cookbook_convertor/md/recipe37.md | 29 ---- linter/cookbook_convertor/md/recipe38.md | 146 ------------------ linter/cookbook_convertor/md/recipe4.md | 31 ---- linter/cookbook_convertor/md/recipe40.md | 46 ------ linter/cookbook_convertor/md/recipe43.md | 41 ----- linter/cookbook_convertor/md/recipe45.md | 34 ---- linter/cookbook_convertor/md/recipe46.md | 33 ---- linter/cookbook_convertor/md/recipe49.md | 35 ----- linter/cookbook_convertor/md/recipe5.md | 63 -------- linter/cookbook_convertor/md/recipe50.md | 49 ------ linter/cookbook_convertor/md/recipe51.md | 42 ----- linter/cookbook_convertor/md/recipe52.md | 59 ------- linter/cookbook_convertor/md/recipe53.md | 56 ------- linter/cookbook_convertor/md/recipe54.md | 10 -- linter/cookbook_convertor/md/recipe55.md | 48 ------ linter/cookbook_convertor/md/recipe56.md | 54 ------- linter/cookbook_convertor/md/recipe59.md | 54 ------- linter/cookbook_convertor/md/recipe60.md | 50 ------ linter/cookbook_convertor/md/recipe61.md | 71 --------- linter/cookbook_convertor/md/recipe65.md | 50 ------ linter/cookbook_convertor/md/recipe66.md | 52 ------- linter/cookbook_convertor/md/recipe69.md | 46 ------ linter/cookbook_convertor/md/recipe71.md | 41 ----- linter/cookbook_convertor/md/recipe74.md | 52 ------- linter/cookbook_convertor/md/recipe76.md | 37 ----- linter/cookbook_convertor/md/recipe79.md | 40 ----- linter/cookbook_convertor/md/recipe8.md | 39 ----- linter/cookbook_convertor/md/recipe80.md | 42 ----- linter/cookbook_convertor/md/recipe81.md | 18 --- linter/cookbook_convertor/md/recipe82.md | 41 ----- linter/cookbook_convertor/md/recipe83.md | 43 ------ linter/cookbook_convertor/md/recipe84.md | 11 -- linter/cookbook_convertor/md/recipe85.md | 56 ------- linter/cookbook_convertor/md/recipe86.md | 49 ------ linter/cookbook_convertor/md/recipe87.md | 32 ---- linter/cookbook_convertor/md/recipe90.md | 67 -------- linter/cookbook_convertor/md/recipe91.md | 47 ------ linter/cookbook_convertor/md/recipe92.md | 48 ------ linter/cookbook_convertor/md/recipe93.md | 58 ------- linter/cookbook_convertor/md/recipe94.md | 48 ------ linter/cookbook_convertor/md/recipe96.md | 84 ---------- linter/cookbook_convertor/md/recipe97.md | 63 -------- linter/cookbook_convertor/md/recipe99.md | 73 --------- .../src/cookbook_convertor.ts | 2 +- linter/docs/rules/recipe10.md | 31 ---- linter/docs/rules/recipe102.md | 4 +- linter/docs/rules/recipe105.md | 7 +- linter/docs/rules/recipe109.md | 8 +- linter/docs/rules/recipe113.md | 4 +- linter/docs/rules/recipe121.md | 6 +- linter/docs/rules/recipe124.md | 39 ----- linter/docs/rules/recipe125.md | 1 - linter/docs/rules/recipe126.md | 1 - linter/docs/rules/recipe129.md | 25 ++- linter/docs/rules/recipe130.md | 8 +- linter/docs/rules/recipe131.md | 4 +- linter/docs/rules/recipe132.md | 17 ++ linter/docs/rules/recipe133.md | 4 +- linter/docs/rules/recipe134.md | 4 +- linter/docs/rules/recipe135.md | 6 +- linter/docs/rules/recipe136.md | 26 +++- linter/docs/rules/recipe138.md | 4 +- linter/docs/rules/recipe140.md | 10 +- linter/docs/rules/recipe141.md | 2 +- linter/docs/rules/recipe143.md | 2 +- linter/docs/rules/recipe144.md | 8 +- linter/docs/rules/recipe145.md | 2 +- linter/docs/rules/recipe146.md | 2 +- linter/docs/rules/recipe147.md | 22 ++- linter/docs/rules/recipe148.md | 42 +++++ linter/docs/rules/recipe16.md | 4 +- linter/docs/rules/recipe19.md | 4 +- linter/docs/rules/recipe22.md | 4 +- linter/docs/rules/recipe25.md | 2 +- linter/docs/rules/recipe27.md | 2 +- linter/docs/rules/recipe3.md | 4 +- linter/docs/rules/recipe30.md | 2 +- linter/docs/rules/recipe31.md | 2 +- linter/docs/rules/recipe32.md | 4 +- linter/docs/rules/recipe34.md | 4 +- linter/docs/rules/recipe35.md | 2 +- linter/docs/rules/recipe37.md | 4 +- linter/docs/rules/recipe38.md | 6 +- linter/docs/rules/recipe43.md | 4 +- linter/docs/rules/recipe46.md | 4 +- linter/docs/rules/recipe50.md | 4 +- linter/docs/rules/recipe52.md | 2 +- linter/docs/rules/recipe53.md | 7 +- linter/docs/rules/recipe60.md | 4 +- linter/docs/rules/recipe63.md | 70 +++++++++ linter/docs/rules/recipe66.md | 2 +- linter/docs/rules/recipe76.md | 6 +- linter/docs/rules/recipe79.md | 4 +- linter/docs/rules/recipe8.md | 4 +- linter/docs/rules/recipe80.md | 7 +- linter/docs/rules/recipe81.md | 2 +- linter/docs/rules/recipe82.md | 2 +- linter/docs/rules/recipe84.md | 22 +++ linter/docs/rules/recipe99.md | 2 +- linter/src/CookBookMsg.ts | 15 +- linter/src/Problems.ts | 4 +- linter/src/TypeScriptLinter.ts | 14 +- linter/src/TypeScriptLinterConfig.ts | 2 +- linter/src/Utils.ts | 6 + linter/test/binary_wrong_types.ts | 9 ++ linter/test/binary_wrong_types.ts.relax.json | 122 +-------------- linter/test/binary_wrong_types.ts.strict.json | 122 +-------------- linter/test/instanceof.ts.relax.json | 5 - linter/test/instanceof.ts.strict.json | 5 - 232 files changed, 668 insertions(+), 5649 deletions(-) delete mode 100644 linter-4.2/docs/rules/recipe10.md delete mode 100644 linter-4.2/docs/rules/recipe124.md create mode 100644 linter-4.2/docs/rules/recipe148.md rename {linter/cookbook_convertor/md => linter-4.2/docs/rules}/recipe63.md (54%) delete mode 100644 linter/cookbook_convertor/md/recipe1.md delete mode 100644 linter/cookbook_convertor/md/recipe10.md delete mode 100644 linter/cookbook_convertor/md/recipe102.md delete mode 100644 linter/cookbook_convertor/md/recipe103.md delete mode 100644 linter/cookbook_convertor/md/recipe104.md delete mode 100644 linter/cookbook_convertor/md/recipe105.md delete mode 100644 linter/cookbook_convertor/md/recipe106.md delete mode 100644 linter/cookbook_convertor/md/recipe109.md delete mode 100644 linter/cookbook_convertor/md/recipe111.md delete mode 100644 linter/cookbook_convertor/md/recipe113.md delete mode 100644 linter/cookbook_convertor/md/recipe114.md delete mode 100644 linter/cookbook_convertor/md/recipe115.md delete mode 100644 linter/cookbook_convertor/md/recipe116.md delete mode 100644 linter/cookbook_convertor/md/recipe118.md delete mode 100644 linter/cookbook_convertor/md/recipe119.md delete mode 100644 linter/cookbook_convertor/md/recipe120.md delete mode 100644 linter/cookbook_convertor/md/recipe121.md delete mode 100644 linter/cookbook_convertor/md/recipe124.md delete mode 100644 linter/cookbook_convertor/md/recipe125.md delete mode 100644 linter/cookbook_convertor/md/recipe126.md delete mode 100644 linter/cookbook_convertor/md/recipe127.md delete mode 100644 linter/cookbook_convertor/md/recipe128.md delete mode 100644 linter/cookbook_convertor/md/recipe129.md delete mode 100644 linter/cookbook_convertor/md/recipe13.md delete mode 100644 linter/cookbook_convertor/md/recipe130.md delete mode 100644 linter/cookbook_convertor/md/recipe131.md delete mode 100644 linter/cookbook_convertor/md/recipe132.md delete mode 100644 linter/cookbook_convertor/md/recipe133.md delete mode 100644 linter/cookbook_convertor/md/recipe134.md delete mode 100644 linter/cookbook_convertor/md/recipe135.md delete mode 100644 linter/cookbook_convertor/md/recipe136.md delete mode 100644 linter/cookbook_convertor/md/recipe137.md delete mode 100644 linter/cookbook_convertor/md/recipe138.md delete mode 100644 linter/cookbook_convertor/md/recipe139.md delete mode 100644 linter/cookbook_convertor/md/recipe14.md delete mode 100644 linter/cookbook_convertor/md/recipe140.md delete mode 100644 linter/cookbook_convertor/md/recipe141.md delete mode 100644 linter/cookbook_convertor/md/recipe142.md delete mode 100644 linter/cookbook_convertor/md/recipe143.md delete mode 100644 linter/cookbook_convertor/md/recipe144.md delete mode 100644 linter/cookbook_convertor/md/recipe15.md delete mode 100644 linter/cookbook_convertor/md/recipe16.md delete mode 100644 linter/cookbook_convertor/md/recipe17.md delete mode 100644 linter/cookbook_convertor/md/recipe19.md delete mode 100644 linter/cookbook_convertor/md/recipe2.md delete mode 100644 linter/cookbook_convertor/md/recipe21.md delete mode 100644 linter/cookbook_convertor/md/recipe22.md delete mode 100644 linter/cookbook_convertor/md/recipe25.md delete mode 100644 linter/cookbook_convertor/md/recipe27.md delete mode 100644 linter/cookbook_convertor/md/recipe28.md delete mode 100644 linter/cookbook_convertor/md/recipe29.md delete mode 100644 linter/cookbook_convertor/md/recipe3.md delete mode 100644 linter/cookbook_convertor/md/recipe30.md delete mode 100644 linter/cookbook_convertor/md/recipe31.md delete mode 100644 linter/cookbook_convertor/md/recipe32.md delete mode 100644 linter/cookbook_convertor/md/recipe34.md delete mode 100644 linter/cookbook_convertor/md/recipe35.md delete mode 100644 linter/cookbook_convertor/md/recipe37.md delete mode 100644 linter/cookbook_convertor/md/recipe38.md delete mode 100644 linter/cookbook_convertor/md/recipe4.md delete mode 100644 linter/cookbook_convertor/md/recipe40.md delete mode 100644 linter/cookbook_convertor/md/recipe43.md delete mode 100644 linter/cookbook_convertor/md/recipe45.md delete mode 100644 linter/cookbook_convertor/md/recipe46.md delete mode 100644 linter/cookbook_convertor/md/recipe49.md delete mode 100644 linter/cookbook_convertor/md/recipe5.md delete mode 100644 linter/cookbook_convertor/md/recipe50.md delete mode 100644 linter/cookbook_convertor/md/recipe51.md delete mode 100644 linter/cookbook_convertor/md/recipe52.md delete mode 100644 linter/cookbook_convertor/md/recipe53.md delete mode 100644 linter/cookbook_convertor/md/recipe54.md delete mode 100644 linter/cookbook_convertor/md/recipe55.md delete mode 100644 linter/cookbook_convertor/md/recipe56.md delete mode 100644 linter/cookbook_convertor/md/recipe59.md delete mode 100644 linter/cookbook_convertor/md/recipe60.md delete mode 100644 linter/cookbook_convertor/md/recipe61.md delete mode 100644 linter/cookbook_convertor/md/recipe65.md delete mode 100644 linter/cookbook_convertor/md/recipe66.md delete mode 100644 linter/cookbook_convertor/md/recipe69.md delete mode 100644 linter/cookbook_convertor/md/recipe71.md delete mode 100644 linter/cookbook_convertor/md/recipe74.md delete mode 100644 linter/cookbook_convertor/md/recipe76.md delete mode 100644 linter/cookbook_convertor/md/recipe79.md delete mode 100644 linter/cookbook_convertor/md/recipe8.md delete mode 100644 linter/cookbook_convertor/md/recipe80.md delete mode 100644 linter/cookbook_convertor/md/recipe81.md delete mode 100644 linter/cookbook_convertor/md/recipe82.md delete mode 100644 linter/cookbook_convertor/md/recipe83.md delete mode 100644 linter/cookbook_convertor/md/recipe84.md delete mode 100644 linter/cookbook_convertor/md/recipe85.md delete mode 100644 linter/cookbook_convertor/md/recipe86.md delete mode 100644 linter/cookbook_convertor/md/recipe87.md delete mode 100644 linter/cookbook_convertor/md/recipe90.md delete mode 100644 linter/cookbook_convertor/md/recipe91.md delete mode 100644 linter/cookbook_convertor/md/recipe92.md delete mode 100644 linter/cookbook_convertor/md/recipe93.md delete mode 100644 linter/cookbook_convertor/md/recipe94.md delete mode 100644 linter/cookbook_convertor/md/recipe96.md delete mode 100644 linter/cookbook_convertor/md/recipe97.md delete mode 100644 linter/cookbook_convertor/md/recipe99.md delete mode 100644 linter/docs/rules/recipe10.md delete mode 100644 linter/docs/rules/recipe124.md create mode 100644 linter/docs/rules/recipe148.md create mode 100644 linter/docs/rules/recipe63.md diff --git a/linter-4.2/cookbook_convertor/src/cookbook_convertor.ts b/linter-4.2/cookbook_convertor/src/cookbook_convertor.ts index 201123993..65279a304 100644 --- a/linter-4.2/cookbook_convertor/src/cookbook_convertor.ts +++ b/linter-4.2/cookbook_convertor/src/cookbook_convertor.ts @@ -36,7 +36,7 @@ const COPYRIGHT_HEADER = "/* \n\ const CODE_PROLOGUE = "export const cookBookMsg: string[] = [];\n\ export const cookBookTag: string[] = [];\n\ \n\ -for( let i = 0; i < 144; i++) {\n\ +for( let i = 0; i < 148; i++) {\n\ cookBookMsg[ i ] = '';\n\ }\n\ "; @@ -372,7 +372,7 @@ function makeOk(): string { needHeader(); console.error( ">>>makeOK HDR>>>: " + doc_lines[ _line ] ); - if( !doc_lines[_line].startsWith(CB_OK) ) { + if( _line >= doc_lines.length || !doc_lines[_line].startsWith(CB_OK) ) { return ""; } _line++; _line++; // skip underline diff --git a/linter-4.2/docs/rules/recipe10.md b/linter-4.2/docs/rules/recipe10.md deleted file mode 100644 index cfaa4830f..000000000 --- a/linter-4.2/docs/rules/recipe10.md +++ /dev/null @@ -1,31 +0,0 @@ -# ``bigint`` is not a builtin type, suffix ``n`` for numeric literals is not supported - -Rule ``arkts-no-n-suffix`` - -**Severity: error** - -ArkTS supports ``bigint`` as a part of the standard library, not as a builtin -type. ``n`` suffix for numeric literals is not supported, ``BigInt`` factory -function can be used to produce values of ``bigint`` type. - - -## TypeScript - - -``` - - let a: bigint = 1n - -``` - -## ArkTS - - -``` - - let a = BigInt(1) - let b: bigint = BigInt(2) - -``` - - diff --git a/linter-4.2/docs/rules/recipe102.md b/linter-4.2/docs/rules/recipe102.md index 6776df1b8..598f43ccc 100644 --- a/linter-4.2/docs/rules/recipe102.md +++ b/linter-4.2/docs/rules/recipe102.md @@ -1,10 +1,10 @@ # Interface declarations (extends same property) -Rule ``arkts-no-extend-same-property`` +Rule ``arkts-no-extend-same-prop`` **Severity: error** -In TypeScript, an interface that extends two other interfaces with the same method, +In TypeScript, an interface that extends two other interfaces with the same method must declare that method with a combined result type. It is not allowed in ArkTS because |LANG| does not allow an interface to contain two methods with signatures that are not distinguishable, e.g., two methods that have the same diff --git a/linter-4.2/docs/rules/recipe105.md b/linter-4.2/docs/rules/recipe105.md index e7e9d47bd..f68c49d03 100644 --- a/linter-4.2/docs/rules/recipe105.md +++ b/linter-4.2/docs/rules/recipe105.md @@ -4,11 +4,12 @@ Rule ``arkts-no-prop-existence-check`` **Severity: error** -ArkTS requires that object layout is determined in compile-time and cannot +ArkTS requires that object layout is determined at compile time and cannot be changed at runtime. There for no runtime property-based checks are supported. If you need to do a type cast, use ``as`` operator and use desired properties -and methods. If some property doesn't exist then an attempt to reference it -will result in a compile-time error. +and methods. +If some property does not exist, then an attempt to refer to it results +in a compile-time error. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe109.md b/linter-4.2/docs/rules/recipe109.md index 05dd754c2..ec6ef7f38 100644 --- a/linter-4.2/docs/rules/recipe109.md +++ b/linter-4.2/docs/rules/recipe109.md @@ -4,10 +4,10 @@ Rule ``arkts-no-dyn-prop-decl`` **Severity: error** -ArkTS does not support dynamic property declaration. All object properties must -be declared immediately in the class. While it can be replaced with an array -of objects, it is still better to adhere to the static language paradigm and -declare fields, their names and types explicitly. +ArkTS does not support dynamic property declaration. All object properties +must be declared immediately in the class. While it can be replaced with an +array of objects, it is still better to adhere to the static language paradigm +and declare fields, their names and types explicitly. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe113.md b/linter-4.2/docs/rules/recipe113.md index 26465b677..26a1aa7f5 100644 --- a/linter-4.2/docs/rules/recipe113.md +++ b/linter-4.2/docs/rules/recipe113.md @@ -4,8 +4,8 @@ Rule ``arkts-no-enum-merging`` **Severity: error** -ArkTS does not support merging declratations for ``enum``. -The declaration of each ``enum`` must be kept compact in the code base. +ArkTS does not support merging declratations for ``enum``. The declaration +of each ``enum`` must be kept compact in the code base. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe121.md b/linter-4.2/docs/rules/recipe121.md index ef4631c12..ce8d38e80 100644 --- a/linter-4.2/docs/rules/recipe121.md +++ b/linter-4.2/docs/rules/recipe121.md @@ -4,8 +4,9 @@ Rule ``arkts-no-require`` **Severity: error** -ArkTS does not support importing via ``require``. ``import`` assignment are -not supported either. Use regular ``import`` instead. +ArkTS does not support importing via ``require``. +``import`` assignments are not supported either. +Use regular ``import`` instead. ## TypeScript @@ -31,3 +32,4 @@ not supported either. Use regular ``import`` instead. - Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) + diff --git a/linter-4.2/docs/rules/recipe124.md b/linter-4.2/docs/rules/recipe124.md deleted file mode 100644 index b1a80dc42..000000000 --- a/linter-4.2/docs/rules/recipe124.md +++ /dev/null @@ -1,39 +0,0 @@ -# Export list declaration is not supported - -Rule ``arkts-no-export-list-decl`` - -**Severity: error** - -ArkTS does not support syntax of export list declarations. All exported -entities must be explicitly annotated with the ``export`` keyword. - - -## TypeScript - - -``` - - export { x } - export { x } from "mod" - export { x, y as b, z as c } - -``` - -## ArkTS - - -``` - - let x = 1 - class MyClass {} - export let y = x, z: number = 2 - export RenamedClass = MyClass - -``` - -## See also - -- Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter-4.2/docs/rules/recipe125.md b/linter-4.2/docs/rules/recipe125.md index 4aa7cec5d..50109740e 100644 --- a/linter-4.2/docs/rules/recipe125.md +++ b/linter-4.2/docs/rules/recipe125.md @@ -54,7 +54,6 @@ Other syntax flavors like ``export * as ...`` are not supported. ## See also -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) - Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) diff --git a/linter-4.2/docs/rules/recipe126.md b/linter-4.2/docs/rules/recipe126.md index 59a9551ca..5e4f7f9af 100644 --- a/linter-4.2/docs/rules/recipe126.md +++ b/linter-4.2/docs/rules/recipe126.md @@ -49,7 +49,6 @@ Use regular ``export`` / ``import`` instead. ## See also - Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) - Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) diff --git a/linter-4.2/docs/rules/recipe129.md b/linter-4.2/docs/rules/recipe129.md index fa5e7dc9e..6d41a927b 100644 --- a/linter-4.2/docs/rules/recipe129.md +++ b/linter-4.2/docs/rules/recipe129.md @@ -4,8 +4,9 @@ Rule ``arkts-no-module-wildcards`` **Severity: error** -ArkTS does not supported wildcards in module names because in |LANG|, import -is a compile-time, not a runtime feature. Use ordinary export syntax instead. +ArkTS does not support wildcards in module names because in the language +import is a compile-time, not a runtime feature. +Use ordinary export syntax instead. ## TypeScript @@ -13,11 +14,31 @@ is a compile-time, not a runtime feature. Use ordinary export syntax instead. ``` + // Declaration: declare module "*!text" { const content: string export default content } + // Consuming code: + import fileContent from "some.txt!text" + +``` + +## ArkTS + + +``` + + // Declaration: + declare namespace N { + function foo(x: number): number + } + + // Consuming code: + import * from "module" + console.log("N.foo called: ", N.foo(42)) + ``` ## See also diff --git a/linter-4.2/docs/rules/recipe130.md b/linter-4.2/docs/rules/recipe130.md index 4a5c602e6..b0f094ff9 100644 --- a/linter-4.2/docs/rules/recipe130.md +++ b/linter-4.2/docs/rules/recipe130.md @@ -4,10 +4,10 @@ Rule ``arkts-no-umd`` **Severity: error** -ArkTS does not support universal module definitions (UMD) because in |LANG| -there is no concept of "script" (as opposed to "module"). Besides, in ArkTS -import is a compile-time, not a runtime feature. Use ordinary syntax for -``export`` and ``import`` instead. +ArkTS does not support universal module definitions (UMD) because in the +language there is no concept of "script" (as opposed to "module"). +Besides, in ArkTS import is a compile-time, not a runtime feature. +Use ordinary syntax for ``export`` and ``import`` instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe131.md b/linter-4.2/docs/rules/recipe131.md index a103967cd..9bd40dd8f 100644 --- a/linter-4.2/docs/rules/recipe131.md +++ b/linter-4.2/docs/rules/recipe131.md @@ -4,8 +4,8 @@ Rule ``arkts-no-js-extension`` **Severity: error** -ArkTS does not allow to use ``.js`` extension in module identifiers because it -has its own mechanisms for interoperating with JavaScript. +ArkTS does not allow using ``.js`` extension in module identifiers because +it has its own mechanisms for interoperating with JavaScript. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe132.md b/linter-4.2/docs/rules/recipe132.md index c38299638..517a1c5a6 100644 --- a/linter-4.2/docs/rules/recipe132.md +++ b/linter-4.2/docs/rules/recipe132.md @@ -26,6 +26,23 @@ to the statically typing. ``` +## ArkTS + + +``` + + class CustomError extends Error { + constructor(message?: string) { + // Call parent's constructor, inheritance chain is static and + // cannot be modified in runtime + super(message) + console.log(this instanceof Error) // true + } + } + let ce = new CustomError() + +``` + ## See also - Recipe 136: Prototype assignment is not supported (``arkts-no-prototype-assignment``) diff --git a/linter-4.2/docs/rules/recipe133.md b/linter-4.2/docs/rules/recipe133.md index ab2f0a51e..b9c586300 100644 --- a/linter-4.2/docs/rules/recipe133.md +++ b/linter-4.2/docs/rules/recipe133.md @@ -5,8 +5,8 @@ Rule ``arkts-no-runtime-import`` **Severity: error** ArkTS does not support such "runtime" import expressions as ``await import...`` -because in ArkTS import is a compile-time, not a runtime feature. Use regular -import syntax instead. +because in the language import is a compile-time, not a runtime feature. +Use regular import syntax instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe134.md b/linter-4.2/docs/rules/recipe134.md index 3286e1cbf..60916e809 100644 --- a/linter-4.2/docs/rules/recipe134.md +++ b/linter-4.2/docs/rules/recipe134.md @@ -5,8 +5,8 @@ Rule ``arkts-no-definite-assignment`` **Severity: error** ArkTS does not support definite assignment assertions ``let v!: T`` because -they are considered an excessive compiler hint. Use declaration with -initialization instead. +they are considered an excessive compiler hint. +Use declaration with initialization instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe135.md b/linter-4.2/docs/rules/recipe135.md index 5e7bb8835..df981900a 100644 --- a/linter-4.2/docs/rules/recipe135.md +++ b/linter-4.2/docs/rules/recipe135.md @@ -4,9 +4,9 @@ Rule ``arkts-no-iife`` **Severity: error** -ArkTS does not support IIFEs as namespace declarations because in |LANG|, -anonymous functions cannot serve as namespaces. Use regular syntax for -namespaces instead. +ArkTS does not support IIFEs as namespace declarations because anonymous +functions in the language cannot serve as namespaces. +Use regular syntax for namespaces instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe136.md b/linter-4.2/docs/rules/recipe136.md index 550b95b54..231fe3003 100644 --- a/linter-4.2/docs/rules/recipe136.md +++ b/linter-4.2/docs/rules/recipe136.md @@ -6,7 +6,8 @@ Rule ``arkts-no-prototype-assignment`` 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 the static typing. +applicable to the static typing. Mechanism of classes and / or interfaces +should be used instead to statically "combine" methods to data together. ## TypeScript @@ -14,7 +15,7 @@ applicable to the static typing. ``` - var C = function(p) { + var C = function(p: number) { this.p = p // Compile-time error only with noImplicitThis } @@ -24,8 +25,25 @@ applicable to the static typing. } } - C.prototype.q = function(r) { - return this.p === r + 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 + } } ``` diff --git a/linter-4.2/docs/rules/recipe138.md b/linter-4.2/docs/rules/recipe138.md index 7dfec46f8..843577939 100644 --- a/linter-4.2/docs/rules/recipe138.md +++ b/linter-4.2/docs/rules/recipe138.md @@ -8,8 +8,8 @@ Currently ArkTS does not support utility types from TypeScript extensions to the standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``Record``. -For ``Record`` type, the type of value must be either optional or unioned with -the ``undefined`` type. +For Record type, the type of an indexing expression *rec[index]* is +of * *V | undefined* type. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe140.md b/linter-4.2/docs/rules/recipe140.md index ae347c437..febf6d055 100644 --- a/linter-4.2/docs/rules/recipe140.md +++ b/linter-4.2/docs/rules/recipe140.md @@ -4,12 +4,12 @@ Rule ``arkts-no-func-apply-bind-call`` **Severity: error** -ArkTS does not allow to use standard library functions ``Function.apply``, -``Function.bind``, ``Function.call``. These APIs are needed in the standard +ArkTS does not allow using standard library functions ``Function.apply``, +``Function.bind`` and ``Function.call``. These APIs are needed in the standard library to explicitly set ``this`` parameter for the called function. -In ArkTS semantics of ``this`` is restricted to the conventional OOP style, -and usage of ``this`` in stand-alone functions is prohibited. Thus these -functions are excessive. +In ArkTS the semantics of ``this`` is restricted to the conventional OOP +style, and the usage of ``this`` in stand-alone functions is prohibited. +Thus these functions are excessive. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe141.md b/linter-4.2/docs/rules/recipe141.md index 1e16d75ad..a772b5388 100644 --- a/linter-4.2/docs/rules/recipe141.md +++ b/linter-4.2/docs/rules/recipe141.md @@ -4,7 +4,7 @@ Rule ``arkts-no-readonly-params`` **Severity: error** -Currently ArkTS supports ``readonly`` for properties, but not for parameters. +Currently, ArkTS supports ``readonly`` for properties, but not for parameters. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe143.md b/linter-4.2/docs/rules/recipe143.md index 9dbec44af..444ceadb8 100644 --- a/linter-4.2/docs/rules/recipe143.md +++ b/linter-4.2/docs/rules/recipe143.md @@ -4,7 +4,7 @@ Rule ``arkts-no-import-assertions`` **Severity: error** -ArkTS does not support import assertions because in |LANG|, import is a +ArkTS does not support import assertions because in the language import is a compile-time, not a runtime feature. So asserting correctness of imported APIs in runtime does not make sense for the statically typed language. Use ordinary ``import`` syntax instead. diff --git a/linter-4.2/docs/rules/recipe144.md b/linter-4.2/docs/rules/recipe144.md index 7a2ed2363..556747f0c 100644 --- a/linter-4.2/docs/rules/recipe144.md +++ b/linter-4.2/docs/rules/recipe144.md @@ -4,10 +4,10 @@ Rule ``arkts-limited-stdlib`` **Severity: error** -ArkTS does not allow usage of some APIs from the TypeScript/JavaScript standard library. -The most part of the restricted APIs relates to manipulating objects in -dynamic manner, which is not compatible with the static typing. Following APIs -are prohibited from usage: +ArkTS does not allow using some APIs from the TypeScript/JavaScript standard library. +The most part of the restricted APIs relates to manipulating 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``, ``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt``, diff --git a/linter-4.2/docs/rules/recipe145.md b/linter-4.2/docs/rules/recipe145.md index 022f436ff..92298aae7 100644 --- a/linter-4.2/docs/rules/recipe145.md +++ b/linter-4.2/docs/rules/recipe145.md @@ -6,7 +6,7 @@ Rule ``arkts-strict-typing`` Type checker in ArkTS is not optional, the code must be explicitly and correctly types to be compiled and run. When porting from the standard TypeScript, -following flags should be turned on: ``noImplicitReturns``, +the following flags must be turned on: ``noImplicitReturns``, ``strictFunctionTypes``, ``strictNullChecks``, ``strictPropertyInitialization``. diff --git a/linter-4.2/docs/rules/recipe146.md b/linter-4.2/docs/rules/recipe146.md index 6426faf28..c47a215e5 100644 --- a/linter-4.2/docs/rules/recipe146.md +++ b/linter-4.2/docs/rules/recipe146.md @@ -5,7 +5,7 @@ Rule ``arkts-strict-typing-required`` **Severity: error** Type checker in ArkTS is not optional, the code must be explicitly and -correctly types to be compiled and run. "Suppressing" type checker in-place +correctly typed to be compiled and run. "Suppressing" type checker in-place with special comments is not allowed. In particular, ``@ts-ignore`` and ``@ts-nocheck`` annotations are not supported. diff --git a/linter-4.2/docs/rules/recipe147.md b/linter-4.2/docs/rules/recipe147.md index de1f456d1..f158e98ef 100644 --- a/linter-4.2/docs/rules/recipe147.md +++ b/linter-4.2/docs/rules/recipe147.md @@ -4,8 +4,9 @@ Rule ``arkts-no-ts-deps`` **Severity: error** -Code base implemented in the standard TypeScript currently should not depend on ArkTS -through importing ArkTS code base. Imports in reverse direction are supported. +Currently, the code base implemented in the standard TypeScript language must not +depend on ArkTS through importing the |LANG| code base. Imports in reverse +direction are supported. ## TypeScript @@ -21,6 +22,23 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" + +``` + +## ArkTS + + +``` + + // lib1.ets + export class C { + // ... + } + + // lib2.ets + import { C } from "lib1" + + ``` diff --git a/linter-4.2/docs/rules/recipe148.md b/linter-4.2/docs/rules/recipe148.md new file mode 100644 index 000000000..d17da6816 --- /dev/null +++ b/linter-4.2/docs/rules/recipe148.md @@ -0,0 +1,42 @@ +# No decorators except ArkUI decorators are currently allowed + +Rule ``arkts-no-decorators-except-arkui`` + +**Severity: error** + +Currently, only ArkUI decorators are allowed in the ArkTS. +Any other decorator will cause compile-time error. + + +## TypeScript + + +``` + + function classDecorator(x: any, y: any): void { + // + } + + @classDecorator + class BugReport { + } + + +``` + +## ArkTS + + +``` + + function classDecorator(x: any, y: any): void { + // + } + + @classDecorator // compile-time error: unsupported decorator + class BugReport { + } + +``` + + diff --git a/linter-4.2/docs/rules/recipe16.md b/linter-4.2/docs/rules/recipe16.md index 8fd0da8ee..8e8037fd6 100644 --- a/linter-4.2/docs/rules/recipe16.md +++ b/linter-4.2/docs/rules/recipe16.md @@ -4,8 +4,8 @@ Rule ``arkts-no-multiple-static-blocks`` **Severity: error** -ArkTS does not allow to have sevaral static block for class initialization, -combine static blocks statements to the one static block. +ArkTS does not allow having sevaral static blocks for class initialization. +Combine static block statements into one static block. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe19.md b/linter-4.2/docs/rules/recipe19.md index 41baed871..0d36274e5 100644 --- a/linter-4.2/docs/rules/recipe19.md +++ b/linter-4.2/docs/rules/recipe19.md @@ -4,8 +4,8 @@ Rule ``arkts-no-intersection-types`` **Severity: error** -Currently, ArkTS does not support intersection types. You can use inheritance -as a work-around. +Currently, ArkTS does not support intersection types. Use inheritance +as a workaround. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe22.md b/linter-4.2/docs/rules/recipe22.md index 1ea9a18cb..9637228b2 100644 --- a/linter-4.2/docs/rules/recipe22.md +++ b/linter-4.2/docs/rules/recipe22.md @@ -5,8 +5,8 @@ Rule ``arkts-no-conditional-types`` **Severity: error** ArkTS does not support conditional type aliases. Introduce a new type with -constraints explicitly or rewrite logic with use of ``Object``. ``infer`` -keyword is not supported. +constraints explicitly, or rewrite logic using ``Object``. The keyword +``infer`` is not supported. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe25.md b/linter-4.2/docs/rules/recipe25.md index 035716d5b..8c611cd81 100644 --- a/linter-4.2/docs/rules/recipe25.md +++ b/linter-4.2/docs/rules/recipe25.md @@ -5,7 +5,7 @@ Rule ``arkts-no-ctor-prop-decls`` **Severity: error** ArkTS does not support declaring class fields in the ``constructor``. -You must declare them inside the ``class`` declaration instead. +Declare class fields inside the ``class`` declaration instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe27.md b/linter-4.2/docs/rules/recipe27.md index 776f84abd..79a314308 100644 --- a/linter-4.2/docs/rules/recipe27.md +++ b/linter-4.2/docs/rules/recipe27.md @@ -1,4 +1,4 @@ -# Construct signatures not supported in interfaces +# Construct signatures are not supported in interfaces Rule ``arkts-no-ctor-signatures-iface`` diff --git a/linter-4.2/docs/rules/recipe3.md b/linter-4.2/docs/rules/recipe3.md index 3611a35c2..2c9098805 100644 --- a/linter-4.2/docs/rules/recipe3.md +++ b/linter-4.2/docs/rules/recipe3.md @@ -4,8 +4,8 @@ Rule ``arkts-no-private-identifiers`` **Severity: error** -ArkTS does not private identifiers started with ``#`` symbol, use ``private`` -keyword instead. +ArkTS does not use private identifiers starting with ``#`` symbol, use +the keyword ``private`` instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe30.md b/linter-4.2/docs/rules/recipe30.md index 78cd9278b..d0a069e36 100644 --- a/linter-4.2/docs/rules/recipe30.md +++ b/linter-4.2/docs/rules/recipe30.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-identity`` **Severity: error** Currently, ArkTS does not support structural identity, i.e., the compiler -cannot compare two types' public APIs and decide whether such types are +cannot compare public APIs of two types and decide whether such types are identical. Use other mechanisms (inheritance, interfaces or type aliases) instead. diff --git a/linter-4.2/docs/rules/recipe31.md b/linter-4.2/docs/rules/recipe31.md index bd8337a3c..d2eef94fb 100644 --- a/linter-4.2/docs/rules/recipe31.md +++ b/linter-4.2/docs/rules/recipe31.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-subtyping`` **Severity: error** Currently, ArkTS does not check structural equivalence for type inference, -i.e., the compiler cannot compare two types' public APIs and decide whether +i.e., the compiler cannot compare public APIs of two types and decide whether such types are identical. Use other mechanisms (inheritance or interfaces) instead. diff --git a/linter-4.2/docs/rules/recipe32.md b/linter-4.2/docs/rules/recipe32.md index 6bb5251a6..cc7e41628 100644 --- a/linter-4.2/docs/rules/recipe32.md +++ b/linter-4.2/docs/rules/recipe32.md @@ -5,8 +5,8 @@ Rule ``arkts-no-structural-assignability`` **Severity: error** Currently, ArkTS does not check structural equivalence when checking if types -are assignable to each other, i.e., the compiler cannot compare two types' -public APIs and decide whether such types are identical. Use other mechanisms +are assignable to each other, i.e., the compiler cannot compare public APIs of +two types and decide whether such types are identical. Use other mechanisms (inheritance or interfaces) instead. diff --git a/linter-4.2/docs/rules/recipe34.md b/linter-4.2/docs/rules/recipe34.md index c1536ee24..3e6b617c3 100644 --- a/linter-4.2/docs/rules/recipe34.md +++ b/linter-4.2/docs/rules/recipe34.md @@ -5,8 +5,8 @@ Rule ``arkts-no-inferred-generic-params`` **Severity: error** ArkTS allows to omit generic type parameters if it is possible to infer -the concrete types from the parameters passed to the function. Otherwise a -compile-time error occurs. In particular, inference of generic type parameters +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. diff --git a/linter-4.2/docs/rules/recipe35.md b/linter-4.2/docs/rules/recipe35.md index 0aab3e3bd..9645463e7 100644 --- a/linter-4.2/docs/rules/recipe35.md +++ b/linter-4.2/docs/rules/recipe35.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-inference`` **Severity: error** Currently, ArkTS does not support structural typing, i.e., the compiler cannot -compare two types' public APIs and decide whether such types are identical. +compare public APIs of two types and decide whether such types are identical. Use inheritance and interfaces to specify the relation between the types explicitly. diff --git a/linter-4.2/docs/rules/recipe37.md b/linter-4.2/docs/rules/recipe37.md index f0ee0385f..862c026b2 100644 --- a/linter-4.2/docs/rules/recipe37.md +++ b/linter-4.2/docs/rules/recipe37.md @@ -4,8 +4,8 @@ Rule ``arkts-no-regexp-literals`` **Severity: error** -Currently, ArkTS does not support RegExp literals. Use library call with string -literals instead. +Currently, ArkTS does not support RegExp literals. Use library call with +string literals instead. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe38.md b/linter-4.2/docs/rules/recipe38.md index 62b06f7a9..a0fdb0a06 100644 --- a/linter-4.2/docs/rules/recipe38.md +++ b/linter-4.2/docs/rules/recipe38.md @@ -5,9 +5,9 @@ Rule ``arkts-no-untyped-obj-literals`` **Severity: error** ArkTS supports usage of object literals if the compiler can infer to what -classes or interfaces such literals correspond to. Otherwise, a compile-time -error occurs. Specifically, using literals to initialize classes and interfaces -is not supported in following contexts: +classes or interfaces such literals correspond to. A compile-time error +occurs otherwise. 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 diff --git a/linter-4.2/docs/rules/recipe43.md b/linter-4.2/docs/rules/recipe43.md index e7257c77b..b2ee2d200 100644 --- a/linter-4.2/docs/rules/recipe43.md +++ b/linter-4.2/docs/rules/recipe43.md @@ -5,8 +5,8 @@ Rule ``arkts-no-noninferrable-arr-literals`` **Severity: error** Basically, ArkTS infers the type of an array literal as a union type of its -contents. But if there is at least one element with a non-inferrable type -(e.g. untyped object literal), a compile-time error occurs. +contents. However, a compile-time error occurs if there is at least one +element with a non-inferrable type (e.g. untyped object literal). ## TypeScript diff --git a/linter-4.2/docs/rules/recipe46.md b/linter-4.2/docs/rules/recipe46.md index 71fcbf8a1..cf1ac5cf3 100644 --- a/linter-4.2/docs/rules/recipe46.md +++ b/linter-4.2/docs/rules/recipe46.md @@ -4,8 +4,8 @@ Rule ``arkts-no-func-expressions`` **Severity: error** -ArkTS does not support function expressions, use arrow functions instead -to be explicitly specified. +ArkTS does not support function expressions. Use arrow functions instead +to specify explicitly. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe50.md b/linter-4.2/docs/rules/recipe50.md index 1f839a5e1..cd2738534 100644 --- a/linter-4.2/docs/rules/recipe50.md +++ b/linter-4.2/docs/rules/recipe50.md @@ -4,8 +4,8 @@ Rule ``arkts-no-class-literals`` **Severity: error** -ArkTS does not support class literals. A new named class type must be -introduced explicitly. +ArkTS does not support class literals. Introduce new named class types +explicitly. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe52.md b/linter-4.2/docs/rules/recipe52.md index f4ff3fd4b..fd7e53ae8 100644 --- a/linter-4.2/docs/rules/recipe52.md +++ b/linter-4.2/docs/rules/recipe52.md @@ -6,7 +6,7 @@ Rule ``arkts-no-undefined-prop-access`` ArkTS supports accessing only those class properties that are either declared in the class, or accessible via inheritance. Accessing any other properties is -prohibited and causes compile-time errors. Use proper types to check property +prohibited, and causes compile-time errors. Use proper types to check property existence during compilation. diff --git a/linter-4.2/docs/rules/recipe53.md b/linter-4.2/docs/rules/recipe53.md index ea6c5a8a1..825fe0f5b 100644 --- a/linter-4.2/docs/rules/recipe53.md +++ b/linter-4.2/docs/rules/recipe53.md @@ -4,13 +4,12 @@ Rule ``arkts-as-casts`` **Severity: error** -ArkTS supports ``as`` keyword as the only syntax for type casts. +ArkTS supports the keyword ``as`` as the only syntax for type casts. Incorrect cast causes a compile-time error or runtime ``ClassCastException``. ```` syntax for type casts is not supported. -However, if a **primitive** type (e.g. a ``number`` or a ``boolean``) must be -cast to the reference type, this must be done through the ``new ...`` expression -instead of ``as``. +Use the expression ``new ...`` instead of ``as`` if a **primitive** type +(e.g., a ``number`` or a ``boolean``) must be cast to the reference type. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe60.md b/linter-4.2/docs/rules/recipe60.md index 38b6ca476..0df74f8a6 100644 --- a/linter-4.2/docs/rules/recipe60.md +++ b/linter-4.2/docs/rules/recipe60.md @@ -4,8 +4,8 @@ Rule ``arkts-no-type-query`` **Severity: error** -ArkTS supports ``typeof`` operator only in the expression context. Specifying -type notations using ``typeof`` is not supported. +ArkTS supports ``typeof`` operator only in the expression context. Using +``typeof`` to specify type notations is not supported. ## TypeScript diff --git a/linter/cookbook_convertor/md/recipe63.md b/linter-4.2/docs/rules/recipe63.md similarity index 54% rename from linter/cookbook_convertor/md/recipe63.md rename to linter-4.2/docs/rules/recipe63.md index 47b26ae72..dc35085bd 100644 --- a/linter/cookbook_convertor/md/recipe63.md +++ b/linter-4.2/docs/rules/recipe63.md @@ -1,11 +1,16 @@ -# Binary ``+`` operator supports implicit casts only for numbers and strings +# Binary ``+`` operator supports implicit casts only for numbers, enums and strings Rule ``arkts-no-polymorphic-plus`` **Severity: error** -ArkTS supports implicit casts for ``+`` only for strings and numbers. -Elsewhere, any form of an explicit cast to string is required. +If one of the operands of binary ``+`` operator is +of the string type (including enum string constant), the other operand +can be of any type, and its value is implicitly converted to string. +Otherwise, ArkTS supports implicit casts for ``+`` only for +numbers and numeric enum constants. +ArkTS as TypeScript does not support ``+`` operator for booleans. +Elsewhere, any form of an explicit cast is required. ## TypeScript @@ -25,6 +30,11 @@ Elsewhere, any form of an explicit cast to string is required. let g = (new Object()) + "string" // "[object Object]string" + let i = true + true // JS: 2, TS: compile-time error + let j = true + 2 // JS: 3, TS: compile-time error + let k = E.E1 + true // JS: 1, TS: compile-time error + + ``` ## ArkTS @@ -44,12 +54,17 @@ Elsewhere, any form of an explicit cast to string is required. let g = (new Object()).toString() + "string" + + let i = true + true // compile-time error + let j = true + 2 // compile-time error + let k = E.E1 + true // compile-time error + + ``` ## See also - Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) + diff --git a/linter-4.2/docs/rules/recipe66.md b/linter-4.2/docs/rules/recipe66.md index 10476f234..20bc3b6bd 100644 --- a/linter-4.2/docs/rules/recipe66.md +++ b/linter-4.2/docs/rules/recipe66.md @@ -6,7 +6,7 @@ Rule ``arkts-no-in`` ArkTS does not support the ``in`` operator. However, this operator makes little sense since the object layout is known at compile time and cannot -be modified at runtime. Use ``instanceof`` as a work-around if you still need +be modified at runtime. Use ``instanceof`` as a workaround if you still need to check whether certain class members exist. diff --git a/linter-4.2/docs/rules/recipe76.md b/linter-4.2/docs/rules/recipe76.md index beec4a751..e620ace6b 100644 --- a/linter-4.2/docs/rules/recipe76.md +++ b/linter-4.2/docs/rules/recipe76.md @@ -4,9 +4,9 @@ Rule ``arkts-no-implied-inference`` **Severity: error** -Currently, ArkTS does not support inference of implied types. Use explicit -type notation instead. Use ``Object[]`` if you need containers that hold -data of mixed types. +Currently, ArkTS does not support inference of implied types. +Use explicit type notation instead. +Use ``Object[]`` if you need containers that hold data of mixed types. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe79.md b/linter-4.2/docs/rules/recipe79.md index 15f916438..30bcb8dd4 100644 --- a/linter-4.2/docs/rules/recipe79.md +++ b/linter-4.2/docs/rules/recipe79.md @@ -4,8 +4,8 @@ Rule ``arkts-no-types-in-catch`` **Severity: error** -In TypeScript catch clause variable type annotation must be ``any`` or ``unknown`` -if specified. As ArkTS does not support these types, a type annotation should +In TypeScript, catch clause variable type annotation must be ``any`` or ``unknown`` +if specified. As ArkTS does not support these types, a type annotation must be omitted. diff --git a/linter-4.2/docs/rules/recipe8.md b/linter-4.2/docs/rules/recipe8.md index 327672363..bd35822de 100644 --- a/linter-4.2/docs/rules/recipe8.md +++ b/linter-4.2/docs/rules/recipe8.md @@ -4,8 +4,8 @@ Rule ``arkts-no-any-unknown`` **Severity: error** -ArkTS does not support ``any``, and ``unknown`` types. Please specify types -explicitly. +ArkTS does not support the types ``any`` and ``unknown``. Please specify +types explicitly. ## TypeScript diff --git a/linter-4.2/docs/rules/recipe80.md b/linter-4.2/docs/rules/recipe80.md index 190320e61..5c2b43061 100644 --- a/linter-4.2/docs/rules/recipe80.md +++ b/linter-4.2/docs/rules/recipe80.md @@ -6,8 +6,9 @@ Rule ``arkts-no-for-in`` ArkTS does not support the 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. For arrays, you can iterate with the regular ``for`` loop. +considered redundant because object layout is known at compile time, and +cannot change at runtime. For arrays, you can iterate with the regular +``for`` loop. ## TypeScript @@ -36,7 +37,7 @@ change at runtime. For arrays, you can iterate with the regular ``for`` loop. ## See also -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) +- Recipe 081: Iterable interfaces are not supported (``arkts-no-iterable``) - Recipe 082: ``for-of`` is supported only for arrays and strings (``arkts-for-of-str-arr``) diff --git a/linter-4.2/docs/rules/recipe81.md b/linter-4.2/docs/rules/recipe81.md index 226c41097..541ab965a 100644 --- a/linter-4.2/docs/rules/recipe81.md +++ b/linter-4.2/docs/rules/recipe81.md @@ -1,6 +1,6 @@ # Iterable interfaces are not supported -Rule ``arkts-noiterable`` +Rule ``arkts-no-iterable`` **Severity: error** diff --git a/linter-4.2/docs/rules/recipe82.md b/linter-4.2/docs/rules/recipe82.md index e6c28d9b6..1c2efa50e 100644 --- a/linter-4.2/docs/rules/recipe82.md +++ b/linter-4.2/docs/rules/recipe82.md @@ -36,6 +36,6 @@ but does not support the iteration of objects content. ## See also - Recipe 080: ``for .. in`` is not supported (``arkts-no-for-in``) -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) +- Recipe 081: Iterable interfaces are not supported (``arkts-no-iterable``) diff --git a/linter-4.2/docs/rules/recipe84.md b/linter-4.2/docs/rules/recipe84.md index b0e6a2752..f5d6f4bcb 100644 --- a/linter-4.2/docs/rules/recipe84.md +++ b/linter-4.2/docs/rules/recipe84.md @@ -8,4 +8,26 @@ ArkTS does not support the ``with`` statement. Use other language idioms (including fully qualified names of functions) to achieve the same behaviour. +## TypeScript + + +``` + + with (Math) { // Compile-time error, but JavaScript code still emitted + let r: number = 42 + console.log("Area: ", PI * r * r) + } + +``` + +## ArkTS + + +``` + + let r: number = 42 + console.log("Area: ", Math.PI * r * r) + +``` + diff --git a/linter-4.2/docs/rules/recipe99.md b/linter-4.2/docs/rules/recipe99.md index 23349a239..f0145e2cf 100644 --- a/linter-4.2/docs/rules/recipe99.md +++ b/linter-4.2/docs/rules/recipe99.md @@ -5,7 +5,7 @@ Rule ``arkts-no-spread`` **Severity: error** The only supported scenario for the spread operator is to spread an array into -the rest parameter. Otherwise manually "unpack" data from arrays and objects, +the rest parameter. Otherwise, manually "unpack" data from arrays and objects, where necessary. diff --git a/linter-4.2/src/CookBookMsg.ts b/linter-4.2/src/CookBookMsg.ts index 50cf78a1b..cd0a4c973 100644 --- a/linter-4.2/src/CookBookMsg.ts +++ b/linter-4.2/src/CookBookMsg.ts @@ -16,7 +16,7 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for( let i = 0; i < 147; i++) { +for( let i = 0; i < 148; i++) { cookBookMsg[ i ] = ''; } @@ -29,7 +29,7 @@ cookBookTag[ 6 ] = ''; cookBookTag[ 7 ] = ''; cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)'; cookBookTag[ 9 ] = ''; -cookBookTag[ 10 ] = '"bigint" is not a builtin type, suffix "n" for numeric literals is not supported (arkts-no-n-suffix)'; +cookBookTag[ 10 ] = ''; cookBookTag[ 11 ] = ''; cookBookTag[ 12 ] = ''; cookBookTag[ 13 ] = 'Use "Object[]" instead of tuples (arkts-no-tuples)'; @@ -46,7 +46,7 @@ cookBookTag[ 23 ] = ''; cookBookTag[ 24 ] = ''; cookBookTag[ 25 ] = 'Declaring fields in "constructor" is not supported (arkts-no-ctor-prop-decls)'; cookBookTag[ 26 ] = ''; -cookBookTag[ 27 ] = 'Construct signatures not supported in interfaces (arkts-no-ctor-signatures-iface)'; +cookBookTag[ 27 ] = 'Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)'; cookBookTag[ 28 ] = 'Indexed access types are not supported (arkts-no-aliases-by-index)'; cookBookTag[ 29 ] = 'Indexed access is not supported for fields (arkts-no-props-by-index)'; cookBookTag[ 30 ] = 'Structural identity is not supported (arkts-no-structural-identity)'; @@ -82,7 +82,7 @@ cookBookTag[ 59 ] = '"delete" operator is not supported (arkts-no-delete)'; cookBookTag[ 60 ] = '"typeof" operator is allowed only in expression contexts (arkts-no-type-query)'; cookBookTag[ 61 ] = ''; cookBookTag[ 62 ] = ''; -cookBookTag[ 63 ] = ''; +cookBookTag[ 63 ] = 'Binary "+" operator supports implicit casts only for numbers, enums and strings (arkts-no-polymorphic-plus)'; cookBookTag[ 64 ] = ''; cookBookTag[ 65 ] = '"instanceof" operator is partially supported (arkts-instanceof-ref-types)'; cookBookTag[ 66 ] = '"in" operator is not supported (arkts-no-in)'; @@ -100,7 +100,7 @@ cookBookTag[ 77 ] = ''; cookBookTag[ 78 ] = ''; cookBookTag[ 79 ] = 'Type annotation in catch clause is not supported (arkts-no-types-in-catch)'; cookBookTag[ 80 ] = '"for .. in" is not supported (arkts-no-for-in)'; -cookBookTag[ 81 ] = 'Iterable interfaces are not supported (arkts-noiterable)'; +cookBookTag[ 81 ] = 'Iterable interfaces are not supported (arkts-no-iterable)'; cookBookTag[ 82 ] = '"for-of" is supported only for arrays and strings (arkts-for-of-str-arr)'; cookBookTag[ 83 ] = 'Mapped type expression is not supported (arkts-no-mapped-types)'; cookBookTag[ 84 ] = '"with" statement is not supported (arkts-no-with)'; @@ -121,7 +121,7 @@ cookBookTag[ 98 ] = ''; cookBookTag[ 99 ] = 'It is possible to spread only arrays into the rest parameter (arkts-no-spread)'; cookBookTag[ 100 ] = ''; cookBookTag[ 101 ] = ''; -cookBookTag[ 102 ] = 'Interface declarations (extends same property) (arkts-no-extend-same-property)'; +cookBookTag[ 102 ] = 'Interface declarations (extends same property) (arkts-no-extend-same-prop)'; cookBookTag[ 103 ] = 'Declaration merging is not supported (arkts-no-decl-merging)'; cookBookTag[ 104 ] = 'Interfaces cannot extend classes (arkts-extends-only-class)'; cookBookTag[ 105 ] = 'Property-based runtime type checks are not supported (arkts-no-prop-existence-check)'; @@ -143,7 +143,7 @@ cookBookTag[ 120 ] = '"import default as ..." is not supported (arkts-no-import- cookBookTag[ 121 ] = '"require" and "import" assignment are not supported (arkts-no-require)'; cookBookTag[ 122 ] = ''; cookBookTag[ 123 ] = ''; -cookBookTag[ 124 ] = 'Export list declaration is not supported (arkts-no-export-list-decl)'; +cookBookTag[ 124 ] = ''; cookBookTag[ 125 ] = 'Re-exporting is supported with restrictions (arkts-limited-reexport)'; cookBookTag[ 126 ] = '"export = ..." assignment is not supported (arkts-no-export-assignment)'; cookBookTag[ 127 ] = 'Special "export type" declarations are not supported (arkts-no-special-exports)'; @@ -167,3 +167,4 @@ cookBookTag[ 144 ] = 'Usage of standard library is restricted (arkts-limited-std cookBookTag[ 145 ] = 'Strict type checking is enforced (arkts-strict-typing)'; cookBookTag[ 146 ] = 'Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)'; cookBookTag[ 147 ] = 'No dependencies on TypeScript code are currently allowed (arkts-no-ts-deps)'; +cookBookTag[ 148 ] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; diff --git a/linter-4.2/src/Problems.ts b/linter-4.2/src/Problems.ts index c001b4178..533391f5a 100644 --- a/linter-4.2/src/Problems.ts +++ b/linter-4.2/src/Problems.ts @@ -19,7 +19,7 @@ export enum FaultID { DestructuringParameter, YieldExpression, InterfaceOrEnumMerging, InterfaceExtendsClass, IndexMember, WithStatement, ThrowStatement, IndexedAccessType, UnknownType, ForInStatement, InOperator, KeyOfOperator, ImportFromPath, FunctionExpression, IntersectionType, - ObjectTypeLiteral, AddWithWrongType, BitOpWithWrongType, CommaOperator, LimitedReturnTypeInference, + ObjectTypeLiteral, AddWithWrongType, CommaOperator, LimitedReturnTypeInference, ArrowFunctionWithOmittedTypes, LambdaWithTypeParameters, ClassExpression, DestructuringAssignment, DestructuringDeclaration, ForOfNonArray, VarDeclaration, CatchWithUnsupportedType, DeleteOperator, DeclWithDuplicateName, FuncOptionalParams, UnaryArithmNotNumber, ConstructorType, CallSignature, @@ -85,7 +85,7 @@ faultsAttrs[FaultID.JsxElement] = {cookBookRef: '54',}; faultsAttrs[FaultID.UnaryArithmNotNumber] = {cookBookRef: '55',}; faultsAttrs[FaultID.DeleteOperator] = {cookBookRef: '59',}; faultsAttrs[FaultID.TypeQuery] = {cookBookRef: '60',}; -faultsAttrs[FaultID.BitOpWithWrongType] = {cookBookRef: '61',}; +// remove as rule#61: FaultID.BitOpWithWrongType => {cookBookRef: '61',}; faultsAttrs[FaultID.AddWithWrongType] = {cookBookRef: '63',}; faultsAttrs[FaultID.InstanceofUnsupported] = {cookBookRef: '65',}; faultsAttrs[FaultID.InOperator] = {cookBookRef: '66',}; diff --git a/linter-4.2/src/TypeScriptLinter.ts b/linter-4.2/src/TypeScriptLinter.ts index 8afdf97da..af8ce230f 100644 --- a/linter-4.2/src/TypeScriptLinter.ts +++ b/linter-4.2/src/TypeScriptLinter.ts @@ -888,7 +888,15 @@ export class TypeScriptLinter { let rightOperandType = TypeScriptLinter.tsTypeChecker.getTypeAtLocation(tsRhsExpr); if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.PlusToken) { - if (Utils.isNumberType(leftOperandType) && Utils.isNumberType(rightOperandType)) + if (Utils.isEnumMemberType(leftOperandType) && Utils.isEnumMemberType(rightOperandType)) { + if ( + ( (leftOperandType.getFlags() & (ts.TypeFlags.NumberLike)) && (rightOperandType.getFlags() & (ts.TypeFlags.NumberLike ) ) ) || + ( (leftOperandType.getFlags() & (ts.TypeFlags.StringLike)) && (rightOperandType.getFlags() & (ts.TypeFlags.StringLike ) ) ) + ) + return; + else + this.incrementCounters(node, FaultID.AddWithWrongType); + } else if (Utils.isNumberType(leftOperandType) && Utils.isNumberType(rightOperandType)) return; else if (Utils.isStringType(leftOperandType) || Utils.isStringType(rightOperandType)) return; @@ -906,7 +914,7 @@ export class TypeScriptLinter { ( tsLhsExpr.kind === ts.SyntaxKind.NumericLiteral && !Utils.isIntegerConstantValue(tsLhsExpr as ts.NumericLiteral)) || ( tsRhsExpr.kind === ts.SyntaxKind.NumericLiteral && !Utils.isIntegerConstantValue(tsRhsExpr as ts.NumericLiteral)) ) - this.incrementCounters(node, FaultID.BitOpWithWrongType); + return; // FaultID.BitOpWithWrongType -removed as rule #61 } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.CommaToken) { // CommaOpertor is allowed in 'for' statement initalizer and incrementor let tsExprNode: ts.Node = tsBinaryExpr; diff --git a/linter-4.2/src/TypeScriptLinterConfig.ts b/linter-4.2/src/TypeScriptLinterConfig.ts index 761ce0d6a..5ec6c6ac7 100644 --- a/linter-4.2/src/TypeScriptLinterConfig.ts +++ b/linter-4.2/src/TypeScriptLinterConfig.ts @@ -51,7 +51,7 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.IntersectionType] = 'intersection types and type literals'; LinterConfig.nodeDesc[FaultID.ObjectTypeLiteral] = 'Object type literals'; LinterConfig.nodeDesc[FaultID.AddWithWrongType] = 'binary "+" with wrong operand'; - LinterConfig.nodeDesc[FaultID.BitOpWithWrongType] = 'bit operation with wrong operand'; + // LinterConfig.nodeDesc[FaultID.BitOpWithWrongType] = 'bit operation with wrong operand'; LinterConfig.nodeDesc[FaultID.CommaOperator] = 'comma operator'; LinterConfig.nodeDesc[FaultID.LimitedReturnTypeInference] = 'Functions with limited return type inference'; LinterConfig.nodeDesc[FaultID.ArrowFunctionWithOmittedTypes] = 'Arrow functions with omitted parameter types'; diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 4206677b4..43eba8cce 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -120,6 +120,12 @@ export function isEnumType(tsType: ts.Type): boolean { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.Enum) !== 0; } +export function isEnumMemberType(tsType: ts.Type): boolean { + // Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. + // Must use SymbolFlags to figure out if this is an enum type. + return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.EnumMember) !== 0; +} + export function isObjectLiteralType(tsType: ts.Type): boolean { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.ObjectLiteral) !== 0; } diff --git a/linter-4.2/test/binary_wrong_types.ts b/linter-4.2/test/binary_wrong_types.ts index e62f9d37c..d34dc7b1c 100644 --- a/linter-4.2/test/binary_wrong_types.ts +++ b/linter-4.2/test/binary_wrong_types.ts @@ -104,3 +104,12 @@ const b42 = 2 | 5.5; const b43 = 5.5 | b42; const b44 = 4 ^ 5.5; const b45 = 5.5 ^ b44; + + +let e1 = Const.PI + Const.E; // OK +let e2 = State.FAULT + State.OK; // OK +let e3 = "State: " + State.FAULT; // OK +let e4 = "Const = " + Const.PI; // OK + +let f1 = Const.PI + State.FAULT; // Error +let f2 = State.OK + Const.E; // Error diff --git a/linter-4.2/test/binary_wrong_types.ts.relax.json b/linter-4.2/test/binary_wrong_types.ts.relax.json index f5197b0ef..85286d415 100644 --- a/linter-4.2/test/binary_wrong_types.ts.relax.json +++ b/linter-4.2/test/binary_wrong_types.ts.relax.json @@ -44,130 +44,20 @@ "column": 3, "problem": "EnumMemberNonConstInit" }, - { - "line": 59, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 60, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 61, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 63, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 64, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 65, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 67, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 68, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 69, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 83, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 84, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 85, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 87, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 88, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 89, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 91, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 92, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 93, - "column": 13, - "problem": "BitOpWithWrongType" - }, { "line": 95, "column": 15, "problem": "CommaOperator" }, { - "line": 101, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 102, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 103, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 104, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 105, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 114, + "column": 10, + "problem": "AddWithWrongType" }, { - "line": 106, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 115, + "column": 10, + "problem": "AddWithWrongType" } ] } \ No newline at end of file diff --git a/linter-4.2/test/binary_wrong_types.ts.strict.json b/linter-4.2/test/binary_wrong_types.ts.strict.json index f5197b0ef..85286d415 100644 --- a/linter-4.2/test/binary_wrong_types.ts.strict.json +++ b/linter-4.2/test/binary_wrong_types.ts.strict.json @@ -44,130 +44,20 @@ "column": 3, "problem": "EnumMemberNonConstInit" }, - { - "line": 59, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 60, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 61, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 63, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 64, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 65, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 67, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 68, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 69, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 83, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 84, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 85, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 87, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 88, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 89, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 91, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 92, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 93, - "column": 13, - "problem": "BitOpWithWrongType" - }, { "line": 95, "column": 15, "problem": "CommaOperator" }, { - "line": 101, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 102, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 103, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 104, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 105, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 114, + "column": 10, + "problem": "AddWithWrongType" }, { - "line": 106, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 115, + "column": 10, + "problem": "AddWithWrongType" } ] } \ No newline at end of file diff --git a/linter-4.2/test/instanceof.ts.relax.json b/linter-4.2/test/instanceof.ts.relax.json index f9d548166..cec2272db 100644 --- a/linter-4.2/test/instanceof.ts.relax.json +++ b/linter-4.2/test/instanceof.ts.relax.json @@ -24,11 +24,6 @@ "column": 11, "problem": "InstanceofUnsupported" }, - { - "line": 28, - "column": 12, - "problem": "BitOpWithWrongType" - }, { "line": 30, "column": 11, diff --git a/linter-4.2/test/instanceof.ts.strict.json b/linter-4.2/test/instanceof.ts.strict.json index d95a4cf33..e3679adf5 100644 --- a/linter-4.2/test/instanceof.ts.strict.json +++ b/linter-4.2/test/instanceof.ts.strict.json @@ -24,11 +24,6 @@ "column": 11, "problem": "InstanceofUnsupported" }, - { - "line": 28, - "column": 12, - "problem": "BitOpWithWrongType" - }, { "line": 30, "column": 11, diff --git a/linter/cookbook_convertor/md/recipe1.md b/linter/cookbook_convertor/md/recipe1.md deleted file mode 100644 index 317d04c6b..000000000 --- a/linter/cookbook_convertor/md/recipe1.md +++ /dev/null @@ -1,59 +0,0 @@ -# Objects with property names that are not identifiers are not supported - -Rule ``arkts-identifiers-as-prop-names`` - -**Severity: error** - -ArkTS does not support Objects with name properties that are numbers or -strings. Use classes to access data by property names. Use arrays to access -data by numeric indices. - - -## TypeScript - - -``` - - var x = {"name": 1, 2: 3} - - console.log(x["name"]) - console.log(x[2]) - -``` - -## ArkTS - - -``` - - class X { - public name: number - } - let x = {name: 1} - console.log(x.name) - - let y = [1, 2, 3] - console.log(y[2]) - - // If you still need a container to store keys of different types, - // use Map: - let z = new Map() - z.set("name", 1) - z.set(2, 2) - console.log(z.get("name")) - console.log(z.get(2)) - -``` - -## See also - -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe10.md b/linter/cookbook_convertor/md/recipe10.md deleted file mode 100644 index cfaa4830f..000000000 --- a/linter/cookbook_convertor/md/recipe10.md +++ /dev/null @@ -1,31 +0,0 @@ -# ``bigint`` is not a builtin type, suffix ``n`` for numeric literals is not supported - -Rule ``arkts-no-n-suffix`` - -**Severity: error** - -ArkTS supports ``bigint`` as a part of the standard library, not as a builtin -type. ``n`` suffix for numeric literals is not supported, ``BigInt`` factory -function can be used to produce values of ``bigint`` type. - - -## TypeScript - - -``` - - let a: bigint = 1n - -``` - -## ArkTS - - -``` - - let a = BigInt(1) - let b: bigint = BigInt(2) - -``` - - diff --git a/linter/cookbook_convertor/md/recipe102.md b/linter/cookbook_convertor/md/recipe102.md deleted file mode 100644 index 6776df1b8..000000000 --- a/linter/cookbook_convertor/md/recipe102.md +++ /dev/null @@ -1,105 +0,0 @@ -# Interface declarations (extends same property) - -Rule ``arkts-no-extend-same-property`` - -**Severity: error** - -In TypeScript, an interface that extends two other interfaces with the same method, -must declare that method with a combined result type. It is not allowed in -ArkTS because |LANG| does not allow an interface to contain two methods with -signatures that are not distinguishable, e.g., 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 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 - } - } - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe103.md b/linter/cookbook_convertor/md/recipe103.md deleted file mode 100644 index b1b794454..000000000 --- a/linter/cookbook_convertor/md/recipe103.md +++ /dev/null @@ -1,47 +0,0 @@ -# Declaration merging is not supported - -Rule ``arkts-no-decl-merging`` - -**Severity: error** - -ArkTS does not support merging declratations. All definitions of classes, -interfaces and so on must be kept compact in the code base. - - -## 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 - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe104.md b/linter/cookbook_convertor/md/recipe104.md deleted file mode 100644 index 88007dab5..000000000 --- a/linter/cookbook_convertor/md/recipe104.md +++ /dev/null @@ -1,41 +0,0 @@ -# Interfaces cannot extend classes - -Rule ``arkts-extends-only-class`` - -**Severity: error** - -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 - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe105.md b/linter/cookbook_convertor/md/recipe105.md deleted file mode 100644 index e7e9d47bd..000000000 --- a/linter/cookbook_convertor/md/recipe105.md +++ /dev/null @@ -1,73 +0,0 @@ -# Property-based runtime type checks are not supported - -Rule ``arkts-no-prop-existence-check`` - -**Severity: error** - -ArkTS requires that object layout is determined in compile-time and cannot -be changed at runtime. There for no runtime property-based checks are supported. -If you need to do a type cast, use ``as`` operator and use desired properties -and methods. If some property doesn't exist then an attempt to reference it -will result in a compile-time error. - - -## TypeScript - - -``` - - class A { - foo() {} - bar() {} - } - - function getSomeObject() { - return new A() - } - - let obj: any = getSomeObject() - if (obj && obj.foo && obj.bar) { - console.log("Yes") // prints "Yes" in this example - } 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() // Compile-time error: Method some_foo does not - // exist on this type - } - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe106.md b/linter/cookbook_convertor/md/recipe106.md deleted file mode 100644 index 702335964..000000000 --- a/linter/cookbook_convertor/md/recipe106.md +++ /dev/null @@ -1,60 +0,0 @@ -# Constructor function type is not supported - -Rule ``arkts-no-ctor-signatures-funcs`` - -**Severity: error** - -ArkTS does not support the usage of the constructor function type. -Use lambdas instead, as they can be generalized to several types of objects. - - -## TypeScript - - -``` - - class Person { - constructor( - name: string, - age: number - ) {} - } - - type PersonConstructor = new (name: string, age: number) => Person - - function createPerson( - Ctor: PersonConstructor, 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) - -``` - - diff --git a/linter/cookbook_convertor/md/recipe109.md b/linter/cookbook_convertor/md/recipe109.md deleted file mode 100644 index 05dd754c2..000000000 --- a/linter/cookbook_convertor/md/recipe109.md +++ /dev/null @@ -1,69 +0,0 @@ -# Dynamic property declaration is not supported - -Rule ``arkts-no-dyn-prop-decl`` - -**Severity: error** - -ArkTS does not support dynamic property declaration. All object properties must -be declared immediately in the class. While it can be replaced with an array -of objects, it is still better to adhere to the static language paradigm and -declare fields, their names and types explicitly. - - -## TypeScript - - -``` - - class Person { - name: string = "" - age: number = 0; // semicolon is required here - [key: string]: string | number - } - - const person: Person = { - name: "John", - age: 30, - email: "john@example.com", - phone: 1234567890, - } - -``` - -## ArkTS - - -``` - - class Person { - name: string - age: number - email: string - phone: number - - constructor(name: string, age: number, email: string, phone: number) { - this.name = name - this.age = age - this.email = email - this.phone = phone - } - } - - function main(): void { - const person: Person = new Person("John", 30, "john@example.com", 1234567890) - } - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe111.md b/linter/cookbook_convertor/md/recipe111.md deleted file mode 100644 index d211bb011..000000000 --- a/linter/cookbook_convertor/md/recipe111.md +++ /dev/null @@ -1,56 +0,0 @@ -# Enumeration members can be initialized only with compile time expressions of the same type - -Rule ``arkts-no-enum-mixed-types`` - -**Severity: error** - -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 time. - - -## 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" - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe113.md b/linter/cookbook_convertor/md/recipe113.md deleted file mode 100644 index 26465b677..000000000 --- a/linter/cookbook_convertor/md/recipe113.md +++ /dev/null @@ -1,45 +0,0 @@ -# ``enum`` declaration merging is not supported - -Rule ``arkts-no-enum-merging`` - -**Severity: error** - -ArkTS does not support merging declratations for ``enum``. -The declaration of each ``enum`` must be kept compact in the code base. - - -## TypeScript - - -``` - - enum Color { - RED, - GREEN - } - enum Color { - YELLOW = 2 - } - enum Color { - BLACK = 3, - BLUE - } - -``` - -## ArkTS - - -``` - - enum Color { - RED, - GREEN, - YELLOW, - BLACK, - BLUE - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe114.md b/linter/cookbook_convertor/md/recipe114.md deleted file mode 100644 index 83adbec65..000000000 --- a/linter/cookbook_convertor/md/recipe114.md +++ /dev/null @@ -1,38 +0,0 @@ -# Namespaces cannot be used as objects - -Rule ``arkts-no-ns-as-obj`` - -**Severity: error** - -ArkTS does not support the usage of namespaces as objects. -Classes or modules can be interpreted as analogues 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 - -``` - - diff --git a/linter/cookbook_convertor/md/recipe115.md b/linter/cookbook_convertor/md/recipe115.md deleted file mode 100644 index 813638578..000000000 --- a/linter/cookbook_convertor/md/recipe115.md +++ /dev/null @@ -1,21 +0,0 @@ -# Scripts and modules - -Rule ``arkts-no-scripts`` - -**Severity: error** - -In general, scripts and modules in ArkTS are very close to TypeScript. -Differences are described in separate recipes. - - -## See also - -- Recipe 118: Special import type declarations are not supported (``arkts-no-special-imports``) -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` is not supported (``arkts-no-require``) -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 125: Re-exporting is not supported (``arkts-no-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter/cookbook_convertor/md/recipe116.md b/linter/cookbook_convertor/md/recipe116.md deleted file mode 100644 index 3fe4c275b..000000000 --- a/linter/cookbook_convertor/md/recipe116.md +++ /dev/null @@ -1,41 +0,0 @@ -# Non-declaration statements in namespaces are not supported - -Rule ``arkts-no-ns-statements`` - -**Severity: error** - -ArkTS does not support statements in namespaces. Use a function to exectute -statements. - - -## TypeScript - - -``` - - namespace A { - export let x: number - x = 1 - } - -``` - -## ArkTS - - -``` - - namespace A { - export let x: number - - export function init() { - x = 1 - } - } - - // Initialization function should be called to execute statements: - A.init() - -``` - - diff --git a/linter/cookbook_convertor/md/recipe118.md b/linter/cookbook_convertor/md/recipe118.md deleted file mode 100644 index 5cd2e85ed..000000000 --- a/linter/cookbook_convertor/md/recipe118.md +++ /dev/null @@ -1,39 +0,0 @@ -# Special import type declarations are not supported - -Rule ``arkts-no-special-imports`` - -**Severity: error** - -ArkTS does not have a special notation for importing types. -Use ordinary import instead. - - -## TypeScript - - -``` - - // Re-using the same import - import { APIResponseType } from "./api" - - // Explicitly use import type - import type { APIResponseType } from "./api" - -``` - -## ArkTS - - -``` - - import { APIResponseType } from "./api" - -``` - -## See also - -- Recipe 119: Importing a module for side-effects only is not supported (``arkts-no-side-effects-imports``) -- Recipe 120: ``import default as ...`` is not supported (``arkts-no-import-default-as``) -- Recipe 121: ``require`` is not supported (``arkts-no-require``) - - diff --git a/linter/cookbook_convertor/md/recipe119.md b/linter/cookbook_convertor/md/recipe119.md deleted file mode 100644 index 9c03707f8..000000000 --- a/linter/cookbook_convertor/md/recipe119.md +++ /dev/null @@ -1,37 +0,0 @@ -# Importing a module for side-effects only is not supported - -Rule ``arkts-no-side-effects-imports`` - -**Severity: error** - -ArkTS does not support global variables like ``window`` to avoid -side-effects during module importing. All variables marked as export can be -accessed through the ``*`` syntax. - - -## TypeScript - - -``` - - // === module at "path/to/module.ts" - export const EXAMPLE_VALUE = 42 - - // Set a global variable - window.MY_GLOBAL_VAR = "Hello, world!" - - // ==== using this module: - import "path/to/module" - -``` - -## ArkTS - - -``` - - import * from "path/to/module" - -``` - - diff --git a/linter/cookbook_convertor/md/recipe120.md b/linter/cookbook_convertor/md/recipe120.md deleted file mode 100644 index dd38b2bf2..000000000 --- a/linter/cookbook_convertor/md/recipe120.md +++ /dev/null @@ -1,29 +0,0 @@ -# ``import default as ...`` is not supported - -Rule ``arkts-no-import-default-as`` - -**Severity: error** - -ArkTS does not support ``import default as ...`` syntax. -Use explicit ``import ... from ...`` instead. - - -## TypeScript - - -``` - - import { default as d } from "mod" - -``` - -## ArkTS - - -``` - - import d from "mod" - -``` - - diff --git a/linter/cookbook_convertor/md/recipe121.md b/linter/cookbook_convertor/md/recipe121.md deleted file mode 100644 index 918ae2aed..000000000 --- a/linter/cookbook_convertor/md/recipe121.md +++ /dev/null @@ -1,28 +0,0 @@ -# ``require`` is not supported - -Rule ``arkts-no-require`` - -**Severity: error** - -ArkTS does not support importing via ``require``. Use ``import`` instead. - - -## TypeScript - - -``` - - import m = require("mod") - -``` - -## ArkTS - - -``` - - import * as m from "mod" - -``` - - diff --git a/linter/cookbook_convertor/md/recipe124.md b/linter/cookbook_convertor/md/recipe124.md deleted file mode 100644 index d073d262c..000000000 --- a/linter/cookbook_convertor/md/recipe124.md +++ /dev/null @@ -1,39 +0,0 @@ -# Export list declaration is not supported - -Rule ``arkts-no-export-list-decl`` - -**Severity: error** - -ArkTS does not support syntax of export list declarations. All exported -entities must be explicitly annotated with the ``export`` keyword. - - -## TypeScript - - -``` - - export { x } - export { x } from "mod" - export { x, y as b, z as c } - -``` - -## ArkTS - - -``` - - let x = 1 - class MyClass {} - export let y = x, z: number = 2 - export RenamedClass = MyClass - -``` - -## See also - -- Recipe 125: Re-exporting is not supported (``arkts-no-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter/cookbook_convertor/md/recipe125.md b/linter/cookbook_convertor/md/recipe125.md deleted file mode 100644 index 624ff218f..000000000 --- a/linter/cookbook_convertor/md/recipe125.md +++ /dev/null @@ -1,57 +0,0 @@ -# Re-exporting is not supported - -Rule ``arkts-no-reexport`` - -**Severity: error** - -ArkTS does not support re-exporting. All desired entities must be -imported explicitly from the modules that export them. - - -## TypeScript - - -``` - - // module1 - export class MyClass { - // ... - } - - // module2 - export { MyClass } from "module1" - - // consumer module - import { MyClass } from "module2" - - const myInstance = new MyClass() - -``` - -## ArkTS - - -``` - - // module1 - export class MyClass { - // ... - } - - // module2 - // some stuff - - // consumer module - import { MyClass } from "module1" - import * from "module2" - - const myInstance = new MyClass() - -``` - -## See also - -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter/cookbook_convertor/md/recipe126.md b/linter/cookbook_convertor/md/recipe126.md deleted file mode 100644 index 37d6fff4b..000000000 --- a/linter/cookbook_convertor/md/recipe126.md +++ /dev/null @@ -1,54 +0,0 @@ -# ``export = ...`` assignment is not supported - -Rule ``arkts-no-export-assignment`` - -**Severity: error** - -ArkTS does not support ``export = ...`` syntax. -Use regular ``export`` / ``import`` 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.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 - -``` - -## See also - -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) -- Recipe 125: Re-exporting is not supported (``arkts-no-reexport``) - - diff --git a/linter/cookbook_convertor/md/recipe127.md b/linter/cookbook_convertor/md/recipe127.md deleted file mode 100644 index 0a307add9..000000000 --- a/linter/cookbook_convertor/md/recipe127.md +++ /dev/null @@ -1,30 +0,0 @@ -# Special export type declarations are not supported - -Rule ``arkts-no-special-exports`` - -**Severity: error** - -ArkTS does not have a special notation for exporting types. -Use ordinary export instead. - - -## TypeScript - - -``` - - class C {} - export type { C } - -``` - -## ArkTS - - -``` - - export class C {} - -``` - - diff --git a/linter/cookbook_convertor/md/recipe128.md b/linter/cookbook_convertor/md/recipe128.md deleted file mode 100644 index 9a5ccebd4..000000000 --- a/linter/cookbook_convertor/md/recipe128.md +++ /dev/null @@ -1,37 +0,0 @@ -# Ambient module declaration is not supported - -Rule ``arkts-no-ambient-decls`` - -**Severity: error** - -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 "../someModule" - -``` - -## See also - -- Recipe 129: Wildcards in module names are not supported (``arkts-no-module-wildcards``) -- Recipe 131: ``.js`` extension is not allowed in module identifiers (``arkts-no-js-extension``) - - diff --git a/linter/cookbook_convertor/md/recipe129.md b/linter/cookbook_convertor/md/recipe129.md deleted file mode 100644 index fa5e7dc9e..000000000 --- a/linter/cookbook_convertor/md/recipe129.md +++ /dev/null @@ -1,29 +0,0 @@ -# Wildcards in module names are not supported - -Rule ``arkts-no-module-wildcards`` - -**Severity: error** - -ArkTS does not supported wildcards in module names because in |LANG|, import -is a compile-time, not a runtime feature. Use ordinary export syntax instead. - - -## TypeScript - - -``` - - declare module "*!text" { - const content: string - export default content - } - -``` - -## See also - -- Recipe 128: Ambient module declaration is not supported (``arkts-no-ambient-decls``) -- Recipe 130: Universal module definitions (UMD) are not supported (``arkts-no-umd``) -- Recipe 131: ``.js`` extension is not allowed in module identifiers (``arkts-no-js-extension``) - - diff --git a/linter/cookbook_convertor/md/recipe13.md b/linter/cookbook_convertor/md/recipe13.md deleted file mode 100644 index 1fcf6c6f5..000000000 --- a/linter/cookbook_convertor/md/recipe13.md +++ /dev/null @@ -1,33 +0,0 @@ -# Use ``Object[]`` instead of tuples - -Rule ``arkts-no-tuples`` - -**Severity: error** - -Currently, ArkTS does not support tuples. You can use arrays of ``Object`` -(``Object[]``) to emulate tuples. - - -## 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] - -``` - - diff --git a/linter/cookbook_convertor/md/recipe130.md b/linter/cookbook_convertor/md/recipe130.md deleted file mode 100644 index da2aada01..000000000 --- a/linter/cookbook_convertor/md/recipe130.md +++ /dev/null @@ -1,47 +0,0 @@ -# Universal module definitions (UMD) are not supported - -Rule ``arkts-no-umd`` - -**Severity: error** - -ArkTS does not support universal module definitions (UMD) because in |LANG| -there is no concept of "script" (as opposed to "module"). Besides, in ArkTS -import is a compile-time, not a runtime feature. Use ordinary syntax for -``export`` and ``import`` 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) - -``` - -## See also - -- Recipe 129: Wildcards in module names are not supported (``arkts-no-module-wildcards``) - - diff --git a/linter/cookbook_convertor/md/recipe131.md b/linter/cookbook_convertor/md/recipe131.md deleted file mode 100644 index c9f6e9c22..000000000 --- a/linter/cookbook_convertor/md/recipe131.md +++ /dev/null @@ -1,34 +0,0 @@ -# ``.js`` extension is not allowed in module identifiers - -Rule ``arkts-no-js-extension`` - -**Severity: error** - -ArkTS does not allow to use ``.js`` extension in module identifiers because it -has its own mechanisms for interoperating with JavaScript. - - -## TypeScript - - -``` - - import { something } from "./module.js" - -``` - -## ArkTS - - -``` - - import { something } from "./module" - -``` - -## See also - -- Recipe 128: Ambient module declaration is not supported (``arkts-no-ambient-decls``) -- Recipe 129: Wildcards in module names are not supported (``arkts-no-module-wildcards``) - - diff --git a/linter/cookbook_convertor/md/recipe132.md b/linter/cookbook_convertor/md/recipe132.md deleted file mode 100644 index c38299638..000000000 --- a/linter/cookbook_convertor/md/recipe132.md +++ /dev/null @@ -1,33 +0,0 @@ -# ``new.target`` is not supported - -Rule ``arkts-no-new-target`` - -**Severity: error** - -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 the statically typing. - - -## TypeScript - - -``` - - class CustomError extends Error { - constructor(message?: string) { - // 'Error' breaks prototype chain here: - super(message) - - // Restore prototype chain: - Object.setPrototypeOf(this, new.target.prototype) - } - } - -``` - -## See also - -- Recipe 136: Prototype assignment is not supported (``arkts-no-prototype-assignment``) - - diff --git a/linter/cookbook_convertor/md/recipe133.md b/linter/cookbook_convertor/md/recipe133.md deleted file mode 100644 index 222bfdee0..000000000 --- a/linter/cookbook_convertor/md/recipe133.md +++ /dev/null @@ -1,36 +0,0 @@ -# Runtime import expressions are not supported - -Rule ``arkts-no-runtime-import`` - -**Severity: error** - -ArkTS does not support such "runtime" import expressions as ``await import...`` -because in ArkTS import is a compile-time, not a runtime feature. Use regular -import syntax instead. - - -## TypeScript - - -``` - - const zipUtil = await import("./utils/create-zip-file") - -``` - -## ArkTS - - -``` - - import { zipUtil } from "./utils/create-zip-file" - -``` - -## See also - -- Recipe 129: Wildcards in module names are not supported (``arkts-no-module-wildcards``) -- Recipe 130: Universal module definitions (UMD) are not supported (``arkts-no-umd``) -- Recipe 143: Import assertions are not supported (``arkts-no-import-assertions``) - - diff --git a/linter/cookbook_convertor/md/recipe134.md b/linter/cookbook_convertor/md/recipe134.md deleted file mode 100644 index 3286e1cbf..000000000 --- a/linter/cookbook_convertor/md/recipe134.md +++ /dev/null @@ -1,44 +0,0 @@ -# Definite assignment assertions are not supported - -Rule ``arkts-no-definite-assignment`` - -**Severity: error** - -ArkTS does not support definite assignment assertions ``let v!: T`` because -they are considered an excessive compiler hint. Use declaration with -initialization instead. - - -## TypeScript - - -``` - - let x!: number // Hint: x will be initialized before usage - - initialize() - - function initialize() { - x = 10 - } - - console.log("x = " + x) - -``` - -## ArkTS - - -``` - - function initialize() : number { - return 10 - } - - let x: number = initialize() - - console.log("x = " + x) - -``` - - diff --git a/linter/cookbook_convertor/md/recipe135.md b/linter/cookbook_convertor/md/recipe135.md deleted file mode 100644 index 545a49b9b..000000000 --- a/linter/cookbook_convertor/md/recipe135.md +++ /dev/null @@ -1,38 +0,0 @@ -# IIFEs as namespace declarations are not supported - -Rule ``arkts-no-iife`` - -**Severity: error** - -ArkTS does not support IIFEs as namespace declarations because in |LANG|, -anonymous functions cannot serve as namespaces. Use regular syntax for -namespaces instead. - - -## TypeScript - - -``` - - var C = (function() { - function C(n) { - this.p = n - } - return C - })() - C.staticProperty = 1 - -``` - -## ArkTS - - -``` - - namespace C { - // ... - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe136.md b/linter/cookbook_convertor/md/recipe136.md deleted file mode 100644 index eb2ada706..000000000 --- a/linter/cookbook_convertor/md/recipe136.md +++ /dev/null @@ -1,37 +0,0 @@ -# Prototype assignment is not supported - -Rule ``arkts-no-prototype-assignment`` - -**Severity: error** - -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 the static typing. - - -## TypeScript - - -``` - - var C = function(p) { - this.p = p - } - - C.prototype = { - m() { - console.log(this.p) - } - } - - C.prototype.q = function(r) { - return this.p === r - } - -``` - -## See also - -- Recipe 132: ``new.target`` is not supported (``arkts-no-new-target``) - - diff --git a/linter/cookbook_convertor/md/recipe137.md b/linter/cookbook_convertor/md/recipe137.md deleted file mode 100644 index 588cc70f4..000000000 --- a/linter/cookbook_convertor/md/recipe137.md +++ /dev/null @@ -1,44 +0,0 @@ -# ``globalThis`` is not supported - -Rule ``arkts-no-globalthis`` - -**Severity: error** - -ArkTS does not support both global scope and ``globalThis`` because untyped -objects with dynamically changed layout are not supported. - - -## TypeScript - - -``` - - // in a global file: - var abc = 100 - - // Refers to 'abc' from above. - globalThis.abc = 200 - -``` - -## ArkTS - - -``` - - // file1 - export let abc : number = 0 - - // file2 - import * as M from "../file1" - - M.abc = 200 - -``` - -## See also - -- Recipe 139: Declaring properties on functions is not supported (``arkts-no-func-props``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe138.md b/linter/cookbook_convertor/md/recipe138.md deleted file mode 100644 index d0f221081..000000000 --- a/linter/cookbook_convertor/md/recipe138.md +++ /dev/null @@ -1,45 +0,0 @@ -# Utility types are not supported - -Rule ``arkts-no-utility-types`` - -**Severity: error** - -Currently ArkTS does not support utility types from TypeScript extensions to the -standard library (``Omit``, ``Partial``, ``Readonly``, ``Record``, ``Pick``, -etc.). - - -## TypeScript - - -``` - - type Person = { - name: string - age: number - location: string - } - - type QuantumPerson = Omit - -``` - -## ArkTS - - -``` - - class Person { - name: string - age: number - location: string - } - - class QuantumPerson { - name: string - age: number - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe139.md b/linter/cookbook_convertor/md/recipe139.md deleted file mode 100644 index 5b27d1ebf..000000000 --- a/linter/cookbook_convertor/md/recipe139.md +++ /dev/null @@ -1,69 +0,0 @@ -# Declaring properties on functions is not supported - -Rule ``arkts-no-func-props`` - -**Severity: error** - -ArkTS does not support declaring properties on functions because there is no -support for objects with dynamically changing layout. Function objects follow -this rule and their layout cannot be changed in runtime. - - -## 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 { - // ... - } - - function readImage( - path: string, callback: (err: Error, image: MyImage) => void - ) : Promise - { - // async implementation - } - - function readImageSync(path: string) : MyImage { - // sync implementation - } - -``` - -## See also - -- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) - - diff --git a/linter/cookbook_convertor/md/recipe14.md b/linter/cookbook_convertor/md/recipe14.md deleted file mode 100644 index b5e575621..000000000 --- a/linter/cookbook_convertor/md/recipe14.md +++ /dev/null @@ -1,53 +0,0 @@ -# Use ``class`` instead of a type with call signature - -Rule ``arkts-no-call-signatures`` - -**Severity: error** - -ArkTS does not support call signatures in object types. Use classes instead. - - -## 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()) - -``` - -## See also - -- Recipe 015: Use ``class`` instead of a type with constructor signature (``arkts-no-ctor-signatures-type``) - - diff --git a/linter/cookbook_convertor/md/recipe140.md b/linter/cookbook_convertor/md/recipe140.md deleted file mode 100644 index ae347c437..000000000 --- a/linter/cookbook_convertor/md/recipe140.md +++ /dev/null @@ -1,65 +0,0 @@ -# ``Function.apply``, ``Function.bind``, ``Function.call`` are not supported - -Rule ``arkts-no-func-apply-bind-call`` - -**Severity: error** - -ArkTS does not allow to use standard library functions ``Function.apply``, -``Function.bind``, ``Function.call``. These APIs are needed in the standard -library to explicitly set ``this`` parameter for the called function. -In ArkTS semantics of ``this`` is restricted to the conventional OOP style, -and usage of ``this`` in stand-alone functions is prohibited. Thus these -functions are excessive. - - -## TypeScript - - -``` - - const person = { - firstName: "aa", - - fullName: function(): string { - return this.firstName - } - } - - const person1 = { - firstName: "Mary" - } - - // This will log "Mary": - console.log(person.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") - - // This will log "Mary": - console.log(person1.fullName()) - -``` - -## See also - -- Recipe 093: Using ``this`` inside stand-alone functions is not supported (``arkts-no-standalone-this``) - - diff --git a/linter/cookbook_convertor/md/recipe141.md b/linter/cookbook_convertor/md/recipe141.md deleted file mode 100644 index 1e16d75ad..000000000 --- a/linter/cookbook_convertor/md/recipe141.md +++ /dev/null @@ -1,34 +0,0 @@ -# ``readonly T[]`` syntax is not supported - -Rule ``arkts-no-readonly-params`` - -**Severity: error** - -Currently ArkTS supports ``readonly`` for properties, but not for parameters. - - -## TypeScript - - -``` - - function foo(arr: readonly string[]) { - arr.slice() // OK - arr.push("hello!") // Compile-time error - } - -``` - -## ArkTS - - -``` - - function foo(arr: string[]) { - arr.slice() // OK - arr.push("hello!") // OK - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe142.md b/linter/cookbook_convertor/md/recipe142.md deleted file mode 100644 index cca78dc76..000000000 --- a/linter/cookbook_convertor/md/recipe142.md +++ /dev/null @@ -1,50 +0,0 @@ -# ``as const`` assertions are not supported - -Rule ``arkts-no-as-const`` - -**Severity: error** - -ArkTS does not support ``as const`` assertions because in the standard TypeScript -``as const`` annotates literals with corresponding literal types, and ArkTS -does not support 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 { - text : string - } - - // Type 'Label': - let z : Label = { - text: "hello" - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe143.md b/linter/cookbook_convertor/md/recipe143.md deleted file mode 100644 index 946b66efa..000000000 --- a/linter/cookbook_convertor/md/recipe143.md +++ /dev/null @@ -1,38 +0,0 @@ -# Import assertions are not supported - -Rule ``arkts-no-import-assertions`` - -**Severity: error** - -ArkTS does not support import assertions because in |LANG|, import is a -compile-time, not a runtime feature. So asserting correctness of imported APIs -in runtime does not make sense for the statically typed language. Use ordinary -``import`` syntax instead. - - -## TypeScript - - -``` - - import { obj } from "./something.json" assert { type: "json" } - -``` - -## ArkTS - - -``` - - // Correctness of importing T will be checked in compile-time: - import { something } from "./module" - -``` - -## See also - -- Recipe 129: Wildcards in module names are not supported (``arkts-no-module-wildcards``) -- Recipe 130: Universal module definitions (UMD) are not supported (``arkts-no-umd``) -- Recipe 133: Runtime import expressions are not supported (``arkts-no-runtime-import``) - - diff --git a/linter/cookbook_convertor/md/recipe144.md b/linter/cookbook_convertor/md/recipe144.md deleted file mode 100644 index 7a2ed2363..000000000 --- a/linter/cookbook_convertor/md/recipe144.md +++ /dev/null @@ -1,54 +0,0 @@ -# Usage of standard library is restricted - -Rule ``arkts-limited-stdlib`` - -**Severity: error** - -ArkTS does not allow usage of some APIs from the TypeScript/JavaScript standard library. -The most part of the restricted APIs relates to manipulating objects in -dynamic manner, which is not compatible with the static typing. Following APIs -are prohibited from usage: - -Properties and functions of the global object: ``eval``, -``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt``, -``encodeURI``, ``encodeURIComponent``, ``Encode``, -``decodeURI``, ``decodeURIComponent``, ``Decode``, -``escape``, ``unescape``, ``ParseHexOctet`` - -``Object``: ``__proto__``, ``__defineGetter__``, ``__defineSetter__``, -``__lookupGetter__``, ``__lookupSetter__``, ``assign``, ``create``, -``defineProperties``, ``defineProperty``, ``entries``, ``freeze``, -``fromEntries``, ``getOwnPropertyDescriptor``, ``getOwnPropertyDescriptors``, -``getOwnPropertyNames``, ``getOwnPropertySymbols``, ``getPrototypeOf``, -``hasOwn``, ``hasOwnProperty``, ``is``, ``isExtensible``, ``isFrozen``, -``isPrototypeOf``, ``isSealed``, ``keys``, ``preventExtensions``, -``propertyIsEnumerable``, ``seal``, ``setPrototypeOf``, ``values`` - -``Reflect``: ``apply``, ``construct``, ``defineProperty``, ``deleteProperty``, -``get``, ``getOwnPropertyDescriptor``, ``getPrototypeOf``, ``has``, -``isExtensible``, ``ownKeys``, ``preventExtensions``, ``set``, -``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()`` - -``Array``: ``isArray`` - -``ArrayBuffer``: ``isView`` - - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 137: ``globalThis`` is not supported (``arkts-no-globalthis``) - - diff --git a/linter/cookbook_convertor/md/recipe15.md b/linter/cookbook_convertor/md/recipe15.md deleted file mode 100644 index b99784a3c..000000000 --- a/linter/cookbook_convertor/md/recipe15.md +++ /dev/null @@ -1,50 +0,0 @@ -# Use ``class`` instead of a type with constructor signature - -Rule ``arkts-no-ctor-signatures-type`` - -**Severity: error** - -ArkTS does not support constructor signatures in object types. Use classes -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) - } - -``` - -## See also - -- Recipe 014: Use ``class`` instead of a type with call signature (``arkts-no-call-signatures``) - - diff --git a/linter/cookbook_convertor/md/recipe16.md b/linter/cookbook_convertor/md/recipe16.md deleted file mode 100644 index 8fd0da8ee..000000000 --- a/linter/cookbook_convertor/md/recipe16.md +++ /dev/null @@ -1,47 +0,0 @@ -# Only one static block is supported - -Rule ``arkts-no-multiple-static-blocks`` - -**Severity: error** - -ArkTS does not allow to have sevaral static block for class initialization, -combine static blocks statements to the one static block. - - -## 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" - } - } - - -``` - - diff --git a/linter/cookbook_convertor/md/recipe17.md b/linter/cookbook_convertor/md/recipe17.md deleted file mode 100644 index 4dd591c0e..000000000 --- a/linter/cookbook_convertor/md/recipe17.md +++ /dev/null @@ -1,43 +0,0 @@ -# Indexed signatures are not supported - -Rule ``arkts-no-indexed-signatures`` - -**Severity: error** - -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] - -``` - - diff --git a/linter/cookbook_convertor/md/recipe19.md b/linter/cookbook_convertor/md/recipe19.md deleted file mode 100644 index 41baed871..000000000 --- a/linter/cookbook_convertor/md/recipe19.md +++ /dev/null @@ -1,49 +0,0 @@ -# Use inheritance instead of intersection types - -Rule ``arkts-no-intersection-types`` - -**Severity: error** - -Currently, ArkTS does not support intersection types. You can use inheritance -as a work-around. - - -## TypeScript - - -``` - - interface Identity { - id: number - name: string - } - - interface Contact { - email: string - phone: string - } - - type Employee = Identity & Contact - -``` - -## ArkTS - - -``` - - interface Identity { - id: number - name: string - } - - interface Contact { - email: string - phone: string - } - - interface Employee extends Identity, Contact {} - -``` - - diff --git a/linter/cookbook_convertor/md/recipe2.md b/linter/cookbook_convertor/md/recipe2.md deleted file mode 100644 index 623cbff52..000000000 --- a/linter/cookbook_convertor/md/recipe2.md +++ /dev/null @@ -1,49 +0,0 @@ -# ``Symbol()`` API is not supported - -Rule ``arkts-no-symbol`` - -**Severity: error** - -TypeScript has ``Symbol()`` API, which can be used among other things to generate -unique property names at runtime. ArkTS does not support ``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. - - -## TypeScript - - -``` - - const sym = Symbol() - let o = { - [sym]: "value" - } - -``` - -## ArkTS - - -``` - - class SomeClass { - public someProperty : string - } - let o = new SomeClass() - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe21.md b/linter/cookbook_convertor/md/recipe21.md deleted file mode 100644 index 75024ca7b..000000000 --- a/linter/cookbook_convertor/md/recipe21.md +++ /dev/null @@ -1,32 +0,0 @@ -# Returning ``this`` type is not supported - -Rule ``arkts-no-this-as-return-type`` - -**Severity: error** - -ArkTS does not support the returning ``this`` type. Use explicit type instead. - - -## TypeScript - - -``` - - interface ListItem { - getHead(): this - } - -``` - -## ArkTS - - -``` - - interface ListItem { - getHead(): ListItem - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe22.md b/linter/cookbook_convertor/md/recipe22.md deleted file mode 100644 index 1ea9a18cb..000000000 --- a/linter/cookbook_convertor/md/recipe22.md +++ /dev/null @@ -1,40 +0,0 @@ -# Conditional types are not supported - -Rule ``arkts-no-conditional-types`` - -**Severity: error** - -ArkTS does not support conditional type aliases. Introduce a new type with -constraints explicitly or rewrite logic with use of ``Object``. ``infer`` -keyword is not supported. - - -## TypeScript - - -``` - - type X = T extends number ? T : never - - type Y = T extends Array ? Item : never - -``` - -## ArkTS - - -``` - - // Provide explicit contraints within type alias - type X1 = T - - // Rewrite with Object. Less type control, need more type checks for safety - type X2 = Object - - // Item has to be used as a generic parameter and need to be properly - // instantiated - type YI> = Item - -``` - - diff --git a/linter/cookbook_convertor/md/recipe25.md b/linter/cookbook_convertor/md/recipe25.md deleted file mode 100644 index 035716d5b..000000000 --- a/linter/cookbook_convertor/md/recipe25.md +++ /dev/null @@ -1,57 +0,0 @@ -# Declaring fields in ``constructor`` is not supported - -Rule ``arkts-no-ctor-prop-decls`` - -**Severity: error** - -ArkTS does not support declaring class fields in the ``constructor``. -You must declare them inside the ``class`` declaration 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 - } - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe27.md b/linter/cookbook_convertor/md/recipe27.md deleted file mode 100644 index 776f84abd..000000000 --- a/linter/cookbook_convertor/md/recipe27.md +++ /dev/null @@ -1,44 +0,0 @@ -# Construct signatures not supported in interfaces - -Rule ``arkts-no-ctor-signatures-iface`` - -**Severity: error** - -ArkTS does not support construct signatures. Use 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") - } - -``` - -## See also - -- Recipe 015: Use ``class`` instead of a type with constructor signature (``arkts-no-ctor-signatures-type``) - - diff --git a/linter/cookbook_convertor/md/recipe28.md b/linter/cookbook_convertor/md/recipe28.md deleted file mode 100644 index 18a706223..000000000 --- a/linter/cookbook_convertor/md/recipe28.md +++ /dev/null @@ -1,30 +0,0 @@ -# Indexed access types are not supported - -Rule ``arkts-no-aliases-by-index`` - -**Severity: error** - -ArkTS does not support indexed access types. Use the type name instead. - - -## TypeScript - - -``` - - type Point = {x: number, y: number} - type N = Point["x"] // is equal to number - -``` - -## ArkTS - - -``` - - class Point {x: number = 0; y: number = 0} - type N = number - -``` - - diff --git a/linter/cookbook_convertor/md/recipe29.md b/linter/cookbook_convertor/md/recipe29.md deleted file mode 100644 index 9f63d1485..000000000 --- a/linter/cookbook_convertor/md/recipe29.md +++ /dev/null @@ -1,33 +0,0 @@ -# Indexed access is not supported for fields - -Rule ``arkts-no-props-by-index`` - -**Severity: error** - -ArkTS does not support indexed access for class fields. Use dot notation -instead. - - -## TypeScript - - -``` - - class Point {x: number = 0; y: number = 0} - let p: Point = {x: 1, y: 2} - let x = p["x"] - -``` - -## ArkTS - - -``` - - class Point {x: number = 0; y: number = 0} - let p: Point = {x: 1, y: 2} - let x = p.x - -``` - - diff --git a/linter/cookbook_convertor/md/recipe3.md b/linter/cookbook_convertor/md/recipe3.md deleted file mode 100644 index 94348f064..000000000 --- a/linter/cookbook_convertor/md/recipe3.md +++ /dev/null @@ -1,34 +0,0 @@ -# Private '#' identifiers are not supported - -Rule ``arkts-no-private-identifiers`` - -**Severity: error** - -ArkTS does not private identifiers started with ``#`` symbol, use ``private`` -keyword instead. - - -## TypeScript - - -``` - - class C { - foo = 1 - } - -``` - -## ArkTS - - -``` - - class C { - private foo = 1 - } - - -``` - - diff --git a/linter/cookbook_convertor/md/recipe30.md b/linter/cookbook_convertor/md/recipe30.md deleted file mode 100644 index 78cd9278b..000000000 --- a/linter/cookbook_convertor/md/recipe30.md +++ /dev/null @@ -1,51 +0,0 @@ -# Structural identity is not supported - -Rule ``arkts-no-structural-identity`` - -**Severity: error** - -Currently, ArkTS does not support structural identity, i.e., the compiler -cannot compare two types' public APIs and decide whether such types are -identical. Use other mechanisms (inheritance, interfaces or type aliases) -instead. - -For the examples below, types ``X`` and ``Y`` are equivalent (interchangeble) -in TypeScript, while in ArkTS they are not. - - -## TypeScript - - -``` - - interface X { - f(): string - } - - interface Y { // Y is equal to X - f(): string - } - -``` - -## ArkTS - - -``` - - interface X { - f(): string - } - - type Y = X // Y is equal to X - -``` - -## See also - -- Recipe 031: Structural typing is not supported for subtyping / supertyping (``arkts-no-structural-subtyping``) -- Recipe 032: Structural typing is not supported for assignability checks (``arkts-no-structural-assignability``) -- Recipe 035: Structural typing is not supported for type inference (``arkts-no-structural-inference``) - - - diff --git a/linter/cookbook_convertor/md/recipe31.md b/linter/cookbook_convertor/md/recipe31.md deleted file mode 100644 index bd8337a3c..000000000 --- a/linter/cookbook_convertor/md/recipe31.md +++ /dev/null @@ -1,84 +0,0 @@ -# Structural typing is not supported for subtyping / supertyping - -Rule ``arkts-no-structural-subtyping`` - -**Severity: error** - -Currently, ArkTS does not check structural equivalence for type inference, -i.e., the compiler cannot compare two types' public APIs and decide whether -such types are identical. Use other mechanisms (inheritance or interfaces) -instead. - - -## TypeScript - - -``` - - class X { - public foo: number - - constructor() { - this.foo = 0 - } - } - - class Y { - public foo: number - - constructor() { - this.foo = 0 - } - } - - let x = new X() - let y = new Y() - - console.log("Assign X to Y") - y = x - - console.log("Assign Y to X") - x = y - - -``` - -## ArkTS - - -``` - - class X { - public foo: number - - constructor() { - this.foo = 0 - } - } - - // Y is derived from X, which explicitly set subtype / supertype relations: - class Y extends X { - constructor() { - super() - } - } - - let x = new X() - let y = new Y() - - console.log("Assign Y to X") - x = y // ok, X is the super class of Y - - // Cannot assign X to Y - //y = x - compile-time error - - -``` - -## See also - -- Recipe 030: Structural identity is not supported (``arkts-no-structural-identity``) -- Recipe 032: Structural typing is not supported for assignability checks (``arkts-no-structural-assignability``) -- Recipe 035: Structural typing is not supported for type inference (``arkts-no-structural-inference``) - - diff --git a/linter/cookbook_convertor/md/recipe32.md b/linter/cookbook_convertor/md/recipe32.md deleted file mode 100644 index 6bb5251a6..000000000 --- a/linter/cookbook_convertor/md/recipe32.md +++ /dev/null @@ -1,88 +0,0 @@ -# Structural typing is not supported for assignability checks - -Rule ``arkts-no-structural-assignability`` - -**Severity: error** - -Currently, ArkTS does not check structural equivalence when checking if types -are assignable to each other, i.e., the compiler cannot compare two types' -public APIs and decide whether such types are identical. Use other mechanisms -(inheritance or interfaces) instead. - - -## TypeScript - - -``` - - class X { - public foo: number - - constructor() { - this.foo = 0 - } - } - - class Y { - public foo: number - constructor() { - this.foo = 0 - } - } - - let x = new X() - let y = new Y() - - console.log("Assign X to Y") - y = x - - console.log("Assign Y to X") - x = y - -``` - -## ArkTS - - -``` - - interface Z { - foo: number - } - - // X implements interface Z, which makes relation between X and Y explicit. - class X implements Z { - public foo: number - - constructor() { - this.foo = 0 - } - } - - // Y implements interface Z, which makes relation between X and Y explicit. - class Y implements Z { - public foo: number - - constructor() { - this.foo = 0 - } - } - - let x: Z = new X() - let y: Z = new Y() - - console.log("Assign X to Y") - y = x // ok, both are of the same type - - console.log("Assign Y to X") - x = y // ok, both are of the same type - -``` - -## See also - -- Recipe 030: Structural identity is not supported (``arkts-no-structural-identity``) -- Recipe 031: Structural typing is not supported for subtyping / supertyping (``arkts-no-structural-subtyping``) -- Recipe 035: Structural typing is not supported for type inference (``arkts-no-structural-inference``) - - diff --git a/linter/cookbook_convertor/md/recipe34.md b/linter/cookbook_convertor/md/recipe34.md deleted file mode 100644 index c1536ee24..000000000 --- a/linter/cookbook_convertor/md/recipe34.md +++ /dev/null @@ -1,51 +0,0 @@ -# Type inference in case of generic function calls is limited - -Rule ``arkts-no-inferred-generic-params`` - -**Severity: error** - -ArkTS allows to omit generic type parameters if it is possible to infer -the concrete types from the parameters passed to the function. Otherwise a -compile-time error occurs. In particular, inference of generic type parameters -based only on function return types is prohibited. - - -## TypeScript - - -``` - - function choose(x: T, y: T): T { - return Math.random() < 0.5 ? x : y - } - - let x = choose(10, 20) // OK, choose(...) is inferred - let y = choose("10", 20) // Compile-time error - - function greet(): T { - return "Hello" as T - } - let z = greet() // Type of x is inferred as "unknown" - -``` - -## ArkTS - - -``` - - function choose(x: T, y: T): T { - return Math.random() < 0.5 ? x : y - } - - let x = choose(10, 20) // OK, choose(...) is inferred - let y = choose("10", 20) // Compile-time error - - function greet(): T { - return "Hello" as T - } - let z = greet() - -``` - - diff --git a/linter/cookbook_convertor/md/recipe35.md b/linter/cookbook_convertor/md/recipe35.md deleted file mode 100644 index 0aab3e3bd..000000000 --- a/linter/cookbook_convertor/md/recipe35.md +++ /dev/null @@ -1,103 +0,0 @@ -# Structural typing is not supported for type inference - -Rule ``arkts-no-structural-inference`` - -**Severity: error** - -Currently, ArkTS does not support structural typing, i.e., the compiler cannot -compare two types' public APIs and decide whether such types are identical. -Use inheritance and interfaces to specify the relation between the types -explicitly. - - -## TypeScript - - -``` - - class X { - public foo: number - private s: string - - constructor (f: number) { - this.foo = f - this.s = "" - } - - public say(): void { - console.log("X = ", this.foo) - } - } - - class Y { - public foo: number - - constructor (f: number) { - this.foo = f - } - public say(): void { - console.log("Y = ", this.foo) - } - } - - function bar(z: X): void { - z.say() - } - - // X and Y are equivalent because their public API is equivalent. - // Thus the second call is allowed: - bar(new X(1)) - bar(new Y(2) as X) - -``` - -## ArkTS - - -``` - - interface Z { - say(): void - } - - class X implements Z { - public foo: number - private s: string - - constructor (f: number) { - this.foo = f - this.s = "" - } - public say(): void { - console.log("X = ", this.foo) - } - } - - class Y implements Z { - public foo: number - - constructor (f: number) { - this.foo = f - } - public say(): void { - console.log("Y = ", this.foo) - } - } - - function bar(z: Z): void { - z.say() - } - - // X and Y implement the same interface Z, thus both calls are allowed: - bar(new X(1)) - bar(new Y(2)) - -``` - -## See also - -- Recipe 030: Structural identity is not supported (``arkts-no-structural-identity``) -- Recipe 031: Structural typing is not supported for subtyping / supertyping (``arkts-no-structural-subtyping``) -- Recipe 032: Structural typing is not supported for assignability checks (``arkts-no-structural-assignability``) - - diff --git a/linter/cookbook_convertor/md/recipe37.md b/linter/cookbook_convertor/md/recipe37.md deleted file mode 100644 index f0ee0385f..000000000 --- a/linter/cookbook_convertor/md/recipe37.md +++ /dev/null @@ -1,29 +0,0 @@ -# RegExp literals are not supported - -Rule ``arkts-no-regexp-literals`` - -**Severity: error** - -Currently, ArkTS does not support RegExp literals. Use library call with string -literals instead. - - -## TypeScript - - -``` - - let regex: RegExp = /bc*d/ - -``` - -## ArkTS - - -``` - - let regex: RegExp = new RegExp("/bc*d/") - -``` - - diff --git a/linter/cookbook_convertor/md/recipe38.md b/linter/cookbook_convertor/md/recipe38.md deleted file mode 100644 index 62b06f7a9..000000000 --- a/linter/cookbook_convertor/md/recipe38.md +++ /dev/null @@ -1,146 +0,0 @@ -# Object literal must correspond to some explicitly declared class or interface - -Rule ``arkts-no-untyped-obj-literals`` - -**Severity: error** - -ArkTS supports usage of object literals if the compiler can infer to what -classes or interfaces such literals correspond to. Otherwise, a compile-time -error occurs. Specifically, using literals to initialize classes and interfaces -is not supported in following contexts: - -* Initialization of anything that has ``any``, ``Object``, or ``object`` type -* Initialization of classes or interfaces with methods -* Initialization of classes which declare a ``constructor`` with parameters -* Initialization of classes with ``readonly`` fields - - -## 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 - } - - // Structural typing is used to deduce that p is Point: - let p = {x: 5, y: 10} - id_x_y(p) - - // A literal can be contextually (i.e., implicitly) typed as 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 = {} // or 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() is used before literal initialization - // to create a valid object. Since there is no other Point constructors, - // constructor() is automatically added by compiler - } - - function id_x_y(o: Point): Point { - return o - } - - // Explicit type is required for literal initialization - let p: Point = {x: 5, y: 10} - id_x_y(p) - - // id_x_y expects Point explicitly - // New instance of Point is initialized with the literal - id_x_y({x: 5, y: 10}) - -``` - -## See also - -- Recipe 040: Object literals cannot be used as type declarations (``arkts-no-obj-literals-as-types``) -- Recipe 043: Array literals must contain elements of only inferrable types (``arkts-no-noninferrable-arr-literals``) - - diff --git a/linter/cookbook_convertor/md/recipe4.md b/linter/cookbook_convertor/md/recipe4.md deleted file mode 100644 index 92f022f7f..000000000 --- a/linter/cookbook_convertor/md/recipe4.md +++ /dev/null @@ -1,31 +0,0 @@ -# Use unique names for types, namespaces, etc. - -Rule ``arkts-unique-names`` - -**Severity: error** - -Names for types, namespaces and so on must be unique and distinct from other -names, e.g., variable 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 - -``` - - diff --git a/linter/cookbook_convertor/md/recipe40.md b/linter/cookbook_convertor/md/recipe40.md deleted file mode 100644 index 9fd22580f..000000000 --- a/linter/cookbook_convertor/md/recipe40.md +++ /dev/null @@ -1,46 +0,0 @@ -# Object literals cannot be used as type declarations - -Rule ``arkts-no-obj-literals-as-types`` - -**Severity: error** - -ArkTS does not support the usage of object literals to declare -types in place. Declare classes and interfaces explicitly instead. - - -## TypeScript - - -``` - - let o: {x: number, y: number} = { - x: 2, - y: 3 - } - - type S = Set<{x: number, y: number}> - -``` - -## ArkTS - - -``` - - class O { - x: number - y: number - } - - let o: O = {x: 2, y: 3} - - type S = Set - -``` - -## See also - -- Recipe 038: Object literal must correspond to some explicitly declared class or interface (``arkts-no-untyped-obj-literals``) -- Recipe 043: Array literals must contain elements of only inferrable types (``arkts-no-noninferrable-arr-literals``) - - diff --git a/linter/cookbook_convertor/md/recipe43.md b/linter/cookbook_convertor/md/recipe43.md deleted file mode 100644 index e7257c77b..000000000 --- a/linter/cookbook_convertor/md/recipe43.md +++ /dev/null @@ -1,41 +0,0 @@ -# Array literals must contain elements of only inferrable types - -Rule ``arkts-no-noninferrable-arr-literals`` - -**Severity: error** - -Basically, ArkTS infers the type of an array literal as a union type of its -contents. But if there is at least one element with a non-inferrable type -(e.g. untyped object literal), a compile-time error occurs. - - -## 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 is of type "C[]" - let a2: C[] = [{n: 1, s: "1"}, {n: 2, s : "2"}] // ditto - -``` - -## See also - -- Recipe 038: Object literal must correspond to some explicitly declared class or interface (``arkts-no-untyped-obj-literals``) -- Recipe 040: Object literals cannot be used as type declarations (``arkts-no-obj-literals-as-types``) - - diff --git a/linter/cookbook_convertor/md/recipe45.md b/linter/cookbook_convertor/md/recipe45.md deleted file mode 100644 index 20680c932..000000000 --- a/linter/cookbook_convertor/md/recipe45.md +++ /dev/null @@ -1,34 +0,0 @@ -# Lambdas require explicit type annotation for parameters - -Rule ``arkts-explicit-param-types-in-lambdas`` - -**Severity: error** - -Currently, ArkTS requires the types of lambda parameters -to be explicitly specified. - - -## TypeScript - - -``` - - let f = (s) => { // type any is assumed - console.log(s) - } - -``` - -## ArkTS - - -``` - - // Explicit types for lambda parameters are mandatory: - let f = (s: string) => { - console.log(s) - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe46.md b/linter/cookbook_convertor/md/recipe46.md deleted file mode 100644 index 71fcbf8a1..000000000 --- a/linter/cookbook_convertor/md/recipe46.md +++ /dev/null @@ -1,33 +0,0 @@ -# Use arrow functions instead of function expressions - -Rule ``arkts-no-func-expressions`` - -**Severity: error** - -ArkTS does not support function expressions, use arrow functions instead -to be explicitly specified. - - -## TypeScript - - -``` - - let f = function (s: string) { - console.log(s) - } - -``` - -## ArkTS - - -``` - - let f = (s: string) => { - console.log(s) - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe49.md b/linter/cookbook_convertor/md/recipe49.md deleted file mode 100644 index eb06bc02e..000000000 --- a/linter/cookbook_convertor/md/recipe49.md +++ /dev/null @@ -1,35 +0,0 @@ -# Use generic functions instead of generic arrow functions - -Rule ``arkts-no-generic-lambdas`` - -**Severity: error** - -ArkTS does not support generic arrow functions. Use normal generic functions -instead. - - -## TypeScript - - -``` - - let generic_arrow_func = (x: T) => { return x } - - generic_arrow_func("string") - -``` - -## ArkTS - - -``` - - function generic_func(x: T): T { - return x - } - - generic_func("string") - -``` - - diff --git a/linter/cookbook_convertor/md/recipe5.md b/linter/cookbook_convertor/md/recipe5.md deleted file mode 100644 index 4d8fbb2d5..000000000 --- a/linter/cookbook_convertor/md/recipe5.md +++ /dev/null @@ -1,63 +0,0 @@ -# Use ``let`` instead of ``var`` - -Rule ``arkts-no-var`` - -**Severity: error** - -ArkTS does not support ``var``, always use ``let`` instead. - - -## 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 // Visible - scoped_let = 5 // Compile-time error - -``` - -## 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 // Compile-time error - -``` - - diff --git a/linter/cookbook_convertor/md/recipe50.md b/linter/cookbook_convertor/md/recipe50.md deleted file mode 100644 index 1f839a5e1..000000000 --- a/linter/cookbook_convertor/md/recipe50.md +++ /dev/null @@ -1,49 +0,0 @@ -# Class literals are not supported - -Rule ``arkts-no-class-literals`` - -**Severity: error** - -ArkTS does not support class literals. A new named class type must be -introduced explicitly. - - -## TypeScript - - -``` - - const Rectangle = class { - constructor(height: number, width: number) { - this.heigth = height - this.width = width - } - - heigth - width - } - - const rectangle = new Rectangle(0.0, 0.0) - -``` - -## ArkTS - - -``` - - class Rectangle { - constructor(height: number, width: number) { - this.heigth = height - this.width = width - } - - heigth: number - width: number - } - - const rectangle = new Rectangle(0.0, 0.0) - -``` - - diff --git a/linter/cookbook_convertor/md/recipe51.md b/linter/cookbook_convertor/md/recipe51.md deleted file mode 100644 index 9b6ddc1fd..000000000 --- a/linter/cookbook_convertor/md/recipe51.md +++ /dev/null @@ -1,42 +0,0 @@ -# Classes cannot be specified in ``implements`` clause - -Rule ``arkts-implements-only-iface`` - -**Severity: error** - -ArkTS does not allow to specify a class in implements clause. Only interfaces -may be specified. - - -## TypeScript - - -``` - - class C { - foo() {} - } - - class C1 implements C { - foo() {} - } - -``` - -## ArkTS - - -``` - - interface C { - foo() - } - - class C1 implements C { - foo() {} - } - - -``` - - diff --git a/linter/cookbook_convertor/md/recipe52.md b/linter/cookbook_convertor/md/recipe52.md deleted file mode 100644 index 91042ae77..000000000 --- a/linter/cookbook_convertor/md/recipe52.md +++ /dev/null @@ -1,59 +0,0 @@ -# Attempt to access an undefined property is a compile-time error - -Rule ``arkts-no-undefined-prop-access`` - -**Severity: error** - -ArkTS supports accessing only those class properties that are either declared -in the class, or accessible via inheritance. Accessing any other properties is -prohibited and causes compile-time errors. Use proper types to check property -existence during compilation. - - -## TypeScript - - -``` - - let person = {name: "Bob", isEmployee: true} - - let n = person["name"] - let e = person["isEmployee"] - let s = person["office"] // undefined - -``` - -## ArkTS - - -``` - - class Person { - constructor(name: string, isEmployee: boolean) { - this.name = name - this.isEmployee = isEmployee - } - - name: string - isEmployee: boolean - } - - let person = new Person("Bob", true) - let n = person.name - let e = person.isEmployee - let s = person.office // Compile-time error - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe53.md b/linter/cookbook_convertor/md/recipe53.md deleted file mode 100644 index 17c22a056..000000000 --- a/linter/cookbook_convertor/md/recipe53.md +++ /dev/null @@ -1,56 +0,0 @@ -# Only ``as T`` syntax is supported for type casts - -Rule ``arkts-as-casts`` - -**Severity: error** - -ArkTS supports ``as`` keyword as the only syntax for type casts. -Incorrect cast causes a compile-time error or runtime ``ClassCastException``. -```` syntax for type casts is not supported. - - -## 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 = createShape() - - let c2 = createShape() as Circle - - // No report is provided during compilation - // nor during runtime if cast is wrong: - let c3 = createShape() as Square - console.log(c3.y) // undefined - -``` - -## 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 - - // ClassCastException during runtime is thrown: - let c3 = createShape() as Square - -``` - - diff --git a/linter/cookbook_convertor/md/recipe54.md b/linter/cookbook_convertor/md/recipe54.md deleted file mode 100644 index f966c42dd..000000000 --- a/linter/cookbook_convertor/md/recipe54.md +++ /dev/null @@ -1,10 +0,0 @@ -# JSX expressions are not supported - -Rule ``arkts-no-jsx`` - -**Severity: error** - -Do not use JSX since no alternative is provided to rewrite it. - - - diff --git a/linter/cookbook_convertor/md/recipe55.md b/linter/cookbook_convertor/md/recipe55.md deleted file mode 100644 index a03384222..000000000 --- a/linter/cookbook_convertor/md/recipe55.md +++ /dev/null @@ -1,48 +0,0 @@ -# Unary operators ``+``, ``-`` and ``~`` work only on numbers - -Rule ``arkts-no-polymorphic-unops`` - -**Severity: error** - -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 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 - -``` - -## ArkTS - - -``` - - let a = +5 // 5 as int - let b = +"5" // Compile-time error - let c = -5 // -5 as int - let d = -"5" // Compile-time error - let e = ~5 // -6 as int - let f = ~"5" // Compile-time error - let g = +"string" // Compile-time error - -``` - -## See also - -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter/cookbook_convertor/md/recipe56.md b/linter/cookbook_convertor/md/recipe56.md deleted file mode 100644 index 8f1cb613e..000000000 --- a/linter/cookbook_convertor/md/recipe56.md +++ /dev/null @@ -1,54 +0,0 @@ -# Unary ``+`` cannot be used for casting to ``number`` - -Rule ``arkts-no-unary-plus-cast`` - -**Severity: error** - -ArkTS does not support casting from any type to a numeric type -by using the unary ``+`` operator, which can be applied only to -numeric types. - - -## TypeScript - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // -10 as number - let b = +returnString() // NaN - -``` - -## ArkTS - - -``` - - function returnTen(): string { - return "-10" - } - - function returnString(): string { - return "string" - } - - let a = +returnTen() // Compile-time error - let b = +returnString() // Compile-time error - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 061: Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types (``arkts-no-polymorphic-binops``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter/cookbook_convertor/md/recipe59.md b/linter/cookbook_convertor/md/recipe59.md deleted file mode 100644 index d64602e17..000000000 --- a/linter/cookbook_convertor/md/recipe59.md +++ /dev/null @@ -1,54 +0,0 @@ -# ``delete`` operator is not supported - -Rule ``arkts-no-delete`` - -**Severity: error** - -ArkTS assumes that object layout is known at compile time and cannot be -changed at runtime. Thus 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 - - -``` - - // To mimic the original semantics, you may declare a nullable type - // and assign null to mark value absence: - - class Point { - x: number | null - y: number | null - } - - let p = new Point() - p.y = null - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) - - diff --git a/linter/cookbook_convertor/md/recipe60.md b/linter/cookbook_convertor/md/recipe60.md deleted file mode 100644 index 38b6ca476..000000000 --- a/linter/cookbook_convertor/md/recipe60.md +++ /dev/null @@ -1,50 +0,0 @@ -# ``typeof`` operator is allowed only in expression contexts - -Rule ``arkts-no-type-query`` - -**Severity: error** - -ArkTS supports ``typeof`` operator only in the expression context. Specifying -type notations using ``typeof`` is not supported. - - -## 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 - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 066: ``in`` operator is not supported (``arkts-no-in``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe61.md b/linter/cookbook_convertor/md/recipe61.md deleted file mode 100644 index e5bdfd14a..000000000 --- a/linter/cookbook_convertor/md/recipe61.md +++ /dev/null @@ -1,71 +0,0 @@ -# Binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, ``>>``, ``>>>``, ``&``, ``^`` and ``|`` work only on numeric types - -Rule ``arkts-no-polymorphic-binops`` - -**Severity: error** - -ArkTS allows applying binary operators ``*``, ``/``, ``%``, ``-``, ``<<``, -``>>``, ``>>>``, ``&``, ``^`` and ``|`` only to values of numeric types. -Implicit casts from other types to numeric types are prohibited and cause -compile-time errors. - - -## TypeScript - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // 5, not 5.5 - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // 5, not 5.5 - - enum Direction { - Up = -1, - Down - } - let e = Direction.Up >> 1 // -1 - let f = Direction.Up >>> 1 // 2147483647 - - let g = ("10" as any) << 1 // 20 - let h = ("str" as any) << 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## ArkTS - - -``` - - let a = (5 & 5) // 5 - let b = (5.5 & 5.5) // Compile-time error - let c = (5 | 5) // 5 - let d = (5.5 | 5.5) // Compile-time error - - enum Direction { - Up, - Down - } - - let e = Direction.Up >> 1 // 0 - let f = Direction.Up >>> 1 // 0 - - let i = 10 * 5 - let j = 10 / 5 - let k = 10 % 5 - let l = 10 - 5 - -``` - -## See also - -- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) -- Recipe 056: Unary ``+`` cannot be used for casting to ``number`` (``arkts-no-unary-plus-cast``) -- Recipe 063: Binary ``+`` operator supports implicit casts only for numbers and strings (``arkts-no-polymorphic-plus``) - - diff --git a/linter/cookbook_convertor/md/recipe65.md b/linter/cookbook_convertor/md/recipe65.md deleted file mode 100644 index b72b699c3..000000000 --- a/linter/cookbook_convertor/md/recipe65.md +++ /dev/null @@ -1,50 +0,0 @@ -# ``instanceof`` operator is partially supported - -Rule ``arkts-instanceof-ref-types`` - -**Severity: error** - -In TypeScript, the left-hand side of an ``instanceof`` expression must be of type -``any``, an object type or a type parameter, otherwise the result is ``false``. -In ArkTS, the left-hand side expression may be of any reference type, otherwise -a compile-time error occurs. In addition, the left operand in ArkTS cannot be -a type. - - -## TypeScript - - -``` - - class X {} - - let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // true - let d = X instanceof X // false - - // left operand is not of type any - let e = (5.0 as Number) instanceof Number // false - -``` - -## ArkTS - - -``` - - class X {} - - let a = (new X()) instanceof Object // true - let b = (new X()) instanceof X // true - // left operand is a type: - let c = X instanceof Object // Compile-time error - let d = X instanceof X // Compile-time error - - // left operand may be of any reference type, like number - let e = (5.0 as Number) instanceof Number // true - -``` - - diff --git a/linter/cookbook_convertor/md/recipe66.md b/linter/cookbook_convertor/md/recipe66.md deleted file mode 100644 index 10476f234..000000000 --- a/linter/cookbook_convertor/md/recipe66.md +++ /dev/null @@ -1,52 +0,0 @@ -# ``in`` operator is not supported - -Rule ``arkts-no-in`` - -**Severity: error** - -ArkTS does not support the ``in`` operator. However, this operator makes -little sense since the object layout is known at compile time and cannot -be modified at runtime. Use ``instanceof`` as a work-around if you still need -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 { - name: string = "" - } - let p = new Person() - - let b = p instanceof Person // true, and "name" is guaranteed to be present - -``` - -## See also - -- Recipe 001: Objects with property names that are not identifiers are not supported (``arkts-identifiers-as-prop-names``) -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 052: Attempt to access an undefined property is a compile-time error (``arkts-no-undefined-prop-access``) -- Recipe 059: ``delete`` operator is not supported (``arkts-no-delete``) -- Recipe 060: ``typeof`` operator is allowed only in expression contexts (``arkts-no-type-query``) -- Recipe 105: Property-based runtime type checks are not supported (``arkts-no-prop-existence-check``) -- Recipe 109: Dynamic property declaration is not supported (``arkts-no-dyn-prop-decl``) -- Recipe 144: Usage of standard library is restricted (``arkts-limited-stdlib``) - - diff --git a/linter/cookbook_convertor/md/recipe69.md b/linter/cookbook_convertor/md/recipe69.md deleted file mode 100644 index 50d253b2f..000000000 --- a/linter/cookbook_convertor/md/recipe69.md +++ /dev/null @@ -1,46 +0,0 @@ -# Destructuring assignment is not supported - -Rule ``arkts-no-destruct-assignment`` - -**Severity: error** - -ArkTS does not support destructuring assignment. Other idioms (e.g., -using a temporary variable, where applicable) can be used for replacement. - - -## 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 = new Number[data.length - 1] - for (let i = 1; i < data.length; ++i) { - tail[i - 1] = data[i] - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe71.md b/linter/cookbook_convertor/md/recipe71.md deleted file mode 100644 index dacc10297..000000000 --- a/linter/cookbook_convertor/md/recipe71.md +++ /dev/null @@ -1,41 +0,0 @@ -# The comma operator ``,`` is supported only in ``for`` loops - -Rule ``arkts-no-comma-outside-loops`` - -**Severity: error** - -ArkTS supports the comma operator ``,`` only in ``for`` loops. Otherwise, -it is useless as it makes the execution order harder to understand. - - -## TypeScript - - -``` - - for (let i = 0, j = 0; i < 10; ++i, j += 2) { - console.log(i, j) - } - - let x = 0 - x = (++x, x++) // 1 - -``` - -## ArkTS - - -``` - - for (let i = 0, j = 0; i < 10; ++i, j += 2) { - console.log(i, j) - } - - // Use explicit execution order instead of the comma operator: - let x = 0 - ++x - x = x++ - -``` - - diff --git a/linter/cookbook_convertor/md/recipe74.md b/linter/cookbook_convertor/md/recipe74.md deleted file mode 100644 index c52123397..000000000 --- a/linter/cookbook_convertor/md/recipe74.md +++ /dev/null @@ -1,52 +0,0 @@ -# Destructuring variable declarations are not supported - -Rule ``arkts-no-destruct-decls`` - -**Severity: error** - -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 destructured 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 { - x: number = 0.0 - y: number = 0.0 - } - - function returnZeroPoint(): Point { - return new Point() - } - - // Create an intermediate object and work with it field by field - // without name restrictions: - let zp = returnZeroPoint() - let x = zp.x - let y = zp.y - -``` - - diff --git a/linter/cookbook_convertor/md/recipe76.md b/linter/cookbook_convertor/md/recipe76.md deleted file mode 100644 index beec4a751..000000000 --- a/linter/cookbook_convertor/md/recipe76.md +++ /dev/null @@ -1,37 +0,0 @@ -# Inference of implied types is not supported - -Rule ``arkts-no-implied-inference`` - -**Severity: error** - -Currently, ArkTS does not support inference of implied types. Use explicit -type notation instead. Use ``Object[]`` if you need containers that hold -data of mixed types. - - -## TypeScript - - -``` - - let [a, b, c] = [1, "hello", true] - -``` - -## ArkTS - - -``` - - let a = 1 - let b = "hello" - let c = true - - let arr: Object[] = [1, "hello", true] - let a1 = arr[0] - let b1 = arr[1] - let c1 = arr[2] - -``` - - diff --git a/linter/cookbook_convertor/md/recipe79.md b/linter/cookbook_convertor/md/recipe79.md deleted file mode 100644 index 56ac1ea4f..000000000 --- a/linter/cookbook_convertor/md/recipe79.md +++ /dev/null @@ -1,40 +0,0 @@ -# Type annotation in catch clause is not supported - -Rule ``arkts-no-types-in-catch`` - -**Severity: error** - -In TypeScript catch clause variable type annotation must be ``any`` or ``unknown`` -if specified. As ArkTS does not support these types, a type annotation should -be omitted. - - -## TypeScript - - -``` - - try { - // some code - } - catch (a: unknown) {} - -``` - -## ArkTS - - -``` - - try { - // some code - } - catch (a) {} - -``` - -## See also - -- Recipe 087: ``throw`` statements cannot accept values of arbitrary types (``arkts-limited-throw``) - - diff --git a/linter/cookbook_convertor/md/recipe8.md b/linter/cookbook_convertor/md/recipe8.md deleted file mode 100644 index 4c4e1056c..000000000 --- a/linter/cookbook_convertor/md/recipe8.md +++ /dev/null @@ -1,39 +0,0 @@ -# Use explicit types instead of ``any``, ``undefined``, ``unknown`` - -Rule ``arkts-no-any-undefined-unknown`` - -**Severity: error** - -ArkTS does not support ``any``, ``undefined``, and ``unknown`` types. -Specify types explicitly. - - -## TypeScript - - -``` - - var x - console.log(x) // undefined - - var y: any - console.log(y) // undefined - -``` - -## ArkTS - - -``` - - // All variables should have their types specified explicitly: - let x: Object = {} - console.log(x) // {} - -``` - -## See also - -- Recipe 013: Use ``Object[]`` instead of tuples (``arkts-no-tuples``) - - diff --git a/linter/cookbook_convertor/md/recipe80.md b/linter/cookbook_convertor/md/recipe80.md deleted file mode 100644 index 190320e61..000000000 --- a/linter/cookbook_convertor/md/recipe80.md +++ /dev/null @@ -1,42 +0,0 @@ -# ``for .. in`` is not supported - -Rule ``arkts-no-for-in`` - -**Severity: error** - -ArkTS does not support the 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. For arrays, you can iterate with the regular ``for`` loop. - - -## 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]) - } - -``` - -## See also - -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) -- Recipe 082: ``for-of`` is supported only for arrays and strings (``arkts-for-of-str-arr``) - - diff --git a/linter/cookbook_convertor/md/recipe81.md b/linter/cookbook_convertor/md/recipe81.md deleted file mode 100644 index 226c41097..000000000 --- a/linter/cookbook_convertor/md/recipe81.md +++ /dev/null @@ -1,18 +0,0 @@ -# Iterable interfaces are not supported - -Rule ``arkts-noiterable`` - -**Severity: error** - -ArkTS does not support the ``Symbol`` API, ``Symbol.iterator`` and -eventually iterable interfaces. Use arrays and library-level containers to -iterate over data. - - -## See also - -- Recipe 002: ``Symbol()`` API is not supported (``arkts-no-symbol``) -- Recipe 080: ``for .. in`` is not supported (``arkts-no-for-in``) -- Recipe 082: ``for-of`` is supported only for arrays and strings (``arkts-for-of-str-arr``) - - diff --git a/linter/cookbook_convertor/md/recipe82.md b/linter/cookbook_convertor/md/recipe82.md deleted file mode 100644 index 1bd77d931..000000000 --- a/linter/cookbook_convertor/md/recipe82.md +++ /dev/null @@ -1,41 +0,0 @@ -# ``for-of`` is supported only for arrays and strings - -Rule ``arkts-for-of-str-arr`` - -**Severity: error** - -ArkTS supports the iteration over arrays and strings by the ``for .. of`` loop, -but does not support the iteration of objects content. - - -## TypeScript - - -``` - - let a: Set = new Set([1, 2, 3]) - for (let s of a) { - console.log(s) - } - -``` - -## ArkTS - - -``` - - let a: Set = new Set([1, 2, 3]) - let numbers = a.values() - for (let n of numbers) { - console.log(n) - } - -``` - -## See also - -- Recipe 080: ``for .. in`` is not supported (``arkts-no-for-in``) -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) - - diff --git a/linter/cookbook_convertor/md/recipe83.md b/linter/cookbook_convertor/md/recipe83.md deleted file mode 100644 index 3eedbaee4..000000000 --- a/linter/cookbook_convertor/md/recipe83.md +++ /dev/null @@ -1,43 +0,0 @@ -# Mapped type expression is not supported - -Rule ``arkts-no-mapped-types`` - -**Severity: error** - -ArkTS does not support mapped types. Use other language idioms and regular -classes to achieve the same behaviour. - - -## TypeScript - - -``` - - type OptionsFlags = { - [Property in keyof Type]: boolean - } - -``` - -## ArkTS - - -``` - - class C { - n: number = 0 - s: string = "" - } - - class CFlags { - n: boolean = false - s: boolean = false - } - -``` - -## See also - -- Recipe 097: ``keyof`` operator is not supported (``arkts-no-keyof``) - - diff --git a/linter/cookbook_convertor/md/recipe84.md b/linter/cookbook_convertor/md/recipe84.md deleted file mode 100644 index b0e6a2752..000000000 --- a/linter/cookbook_convertor/md/recipe84.md +++ /dev/null @@ -1,11 +0,0 @@ -# ``with`` statement is not supported - -Rule ``arkts-no-with`` - -**Severity: error** - -ArkTS does not support the ``with`` statement. Use other language idioms -(including fully qualified names of functions) to achieve the same behaviour. - - - diff --git a/linter/cookbook_convertor/md/recipe85.md b/linter/cookbook_convertor/md/recipe85.md deleted file mode 100644 index 41db7a1e5..000000000 --- a/linter/cookbook_convertor/md/recipe85.md +++ /dev/null @@ -1,56 +0,0 @@ -# Values computed at runtime are not supported in ``case`` statements - -Rule ``arkts-no-computed-case`` - -**Severity: error** - -ArkTS supports ``case`` statements that contain only compile-time values. -Use ``if`` statements as an alternative. - - -## TypeScript - - -``` - - let x = 2 - let y = 3 - switch (x) { - case 1: - console.log(1) - break - case 2: - console.log(2) - break - case y: - console.log(y) - break - default: - console.log("other") - } - -``` - -## ArkTS - - -``` - - let x = 2 - switch (x) { - case 1: - console.log(1) - break - case 2: - console.log(2) - break - case 3: - console.log(3) - break - default: - console.log("other") - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe86.md b/linter/cookbook_convertor/md/recipe86.md deleted file mode 100644 index d57436d82..000000000 --- a/linter/cookbook_convertor/md/recipe86.md +++ /dev/null @@ -1,49 +0,0 @@ -# ``switch`` statements cannot accept values of arbitrary types - -Rule ``arkts-limited-switch`` - -**Severity: error** - -ArkTS supports the values of the types ``char``, ``byte``, ``short``, ``int``, -``long``, ``Char``, ``Byte``, ``Short``, ``Int``, ``Long``, ``String`` or -``enum`` in ``switch`` statements. Use ``if`` statements in other cases. - - -## TypeScript - - -``` - - class Point { - x: number = 0 - y: number = 0 - } - - let a = new Point() - - switch (a) { - case null: break - default: console.log("not null") - } - -``` - -## ArkTS - - -``` - - class Point { - x: number = 0 - y: number = 0 - } - - let a = new Point() - - if (a != null) { - console.log("not null") - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe87.md b/linter/cookbook_convertor/md/recipe87.md deleted file mode 100644 index a934a37c4..000000000 --- a/linter/cookbook_convertor/md/recipe87.md +++ /dev/null @@ -1,32 +0,0 @@ -# ``throw`` statements cannot accept values of arbitrary types - -Rule ``arkts-limited-throw`` - -**Severity: error** - -ArkTS supports throwing only objects of the class ``Error`` or any -derived class. Throwing an arbitrary type (i.e., a ``number`` or ``string``) -is prohibited. - - -## TypeScript - - -``` - - throw 4 - throw "" - throw new Error() - -``` - -## ArkTS - - -``` - - throw new Error() - -``` - - diff --git a/linter/cookbook_convertor/md/recipe90.md b/linter/cookbook_convertor/md/recipe90.md deleted file mode 100644 index 5ee2428f2..000000000 --- a/linter/cookbook_convertor/md/recipe90.md +++ /dev/null @@ -1,67 +0,0 @@ -# Function return type inference is limited - -Rule ``arkts-no-implicit-return-types`` - -**Severity: error** - -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. In case of any such error, specify the return type -explicitly. - - -## TypeScript - - -``` - - function f(x: number) { - if (x <= 0) { - return x - } - return g(x) - } - - 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 - - -``` - - // Explicit return type is required: - function f(x: number) : number { - if (x <= 0) { - return x - } - return g(x) - } - - // Explicit return type is required: - function g(x: number) : number { - return f(x - 1) - } - - // In this case, return type will be inferred - function doOperation(x: number, y: number) { - return x + y - } - - console.log(f(10)) - console.log(doOperation(2, 3)) - -``` - - diff --git a/linter/cookbook_convertor/md/recipe91.md b/linter/cookbook_convertor/md/recipe91.md deleted file mode 100644 index 84c862983..000000000 --- a/linter/cookbook_convertor/md/recipe91.md +++ /dev/null @@ -1,47 +0,0 @@ -# Destructuring parameter declarations are not supported - -Rule ``arkts-no-destruct-params`` - -**Severity: error** - -ArkTS requires that parameters must be passed directly to the function, and -local names must be assigned manually. - - -## 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) - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe92.md b/linter/cookbook_convertor/md/recipe92.md deleted file mode 100644 index 584a28f9f..000000000 --- a/linter/cookbook_convertor/md/recipe92.md +++ /dev/null @@ -1,48 +0,0 @@ -# Nested functions are not supported - -Rule ``arkts-no-nested-funcs`` - -**Severity: error** - -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.log(message) - } - - let result = a + b - - // Invoking 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.log(message) - } - - let result = a + b - - logToConsole("result is " + result) - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe93.md b/linter/cookbook_convertor/md/recipe93.md deleted file mode 100644 index ceb0cacf5..000000000 --- a/linter/cookbook_convertor/md/recipe93.md +++ /dev/null @@ -1,58 +0,0 @@ -# Using ``this`` inside stand-alone functions is not supported - -Rule ``arkts-no-standalone-this`` - -**Severity: error** - -ArkTS does not support the usage of ``this`` inside stand-alone functions. -``this`` can be used in methods only. - - -## TypeScript - - -``` - - function foo(i: number) { - this.count = i - } - - class A { - count: number = 1 - m = foo - } - - let a = new A() - console.log(a.count) // prints "1" - a.m(2) - console.log(a.count) // prints "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) // prints "1" - a.m(2) - console.log(a.count) // prints "2" - } - -``` - -## See also - -- Recipe 140: ``Function.apply``, ``Function.bind``, ``Function.call`` are not supported (``arkts-no-func-apply-bind-call``) - - diff --git a/linter/cookbook_convertor/md/recipe94.md b/linter/cookbook_convertor/md/recipe94.md deleted file mode 100644 index 8f350dc7f..000000000 --- a/linter/cookbook_convertor/md/recipe94.md +++ /dev/null @@ -1,48 +0,0 @@ -# Generator functions are not supported - -Rule ``arkts-no-generators`` - -**Severity: error** - -Currently, ArkTS does not support generator functions. -Use the ``async`` / ``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.log(num) - } - -``` - -## ArkTS - - -``` - - async function complexNumberProcessing(n : number) : Promise { - // Some complex logic for proccessing the number here - return n - } - - async function foo() { - for (let i = 1; i <= 5; i++) { - console.log(await complexNumberProcessing(i)) - } - } - - foo() - -``` - - diff --git a/linter/cookbook_convertor/md/recipe96.md b/linter/cookbook_convertor/md/recipe96.md deleted file mode 100644 index 4f8885762..000000000 --- a/linter/cookbook_convertor/md/recipe96.md +++ /dev/null @@ -1,84 +0,0 @@ -# Type guarding is supported with ``instanceof`` and ``as`` - -Rule ``arkts-no-is`` - -**Severity: error** - -ArkTS does not support the ``is`` operator, which must be replaced by the -``instanceof`` operator. Note that the fields of an object must be cast to the -appropriate type with the ``as`` operator before use. - - -## 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) // Compile-time error - } else { - console.log(arg.foo) // Compile-time error - 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) // Compile-time error - } else { - let barArg = arg as Bar - console.log(arg.foo) // Compile-time error - console.log(barArg.bar) // OK - } - } - - function main(): void { - doStuff(new Foo()) - doStuff(new Bar()) - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe97.md b/linter/cookbook_convertor/md/recipe97.md deleted file mode 100644 index ec1b161dc..000000000 --- a/linter/cookbook_convertor/md/recipe97.md +++ /dev/null @@ -1,63 +0,0 @@ -# ``keyof`` operator is not supported - -Rule ``arkts-no-keyof`` - -**Severity: error** - -ArkTS has no `keyof` operator because the object layout is defined -at compile time and cannot be changed at runtime. Object fields can only be -accessed directly. - - -## TypeScript - - -``` - - class Point { - x: number = 1 - y: number = 2 - } - - type PointKeys = keyof Point // The type of PointKeys is "x" | "y" - - function getPropertyValue(obj: Point, key: PointKeys) { - return obj[key] - } - - let obj = new Point() - console.log(getPropertyValue(obj, "x")) // prints "1" - console.log(getPropertyValue(obj, "y")) // prints "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() // No such property - return 0 - } - - function main(): void { - let obj = new Point() - console.log(getPropertyValue(obj, "x")) // prints "1" - console.log(getPropertyValue(obj, "y")) // prints "2" - } - -``` - - diff --git a/linter/cookbook_convertor/md/recipe99.md b/linter/cookbook_convertor/md/recipe99.md deleted file mode 100644 index 094f6841e..000000000 --- a/linter/cookbook_convertor/md/recipe99.md +++ /dev/null @@ -1,73 +0,0 @@ -# It is possible to spread only arrays into the rest parameter - -Rule ``arkts-no-spread`` - -**Severity: error** - -The only supported scenario for the spread operator is to spread an array into -the rest parameter. Otherwise manually "unpack" data from arrays and objects, -where necessary. - - -## 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 - } - - function log_numbers(x : number, y : number, z : number) { - console.log(x, y, z) - } - - let numbers : number[] = [0, 1, 2] - sum_numbers(...numbers) - 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) - -``` - - diff --git a/linter/cookbook_convertor/src/cookbook_convertor.ts b/linter/cookbook_convertor/src/cookbook_convertor.ts index 11d3c7766..65279a304 100644 --- a/linter/cookbook_convertor/src/cookbook_convertor.ts +++ b/linter/cookbook_convertor/src/cookbook_convertor.ts @@ -36,7 +36,7 @@ const COPYRIGHT_HEADER = "/* \n\ const CODE_PROLOGUE = "export const cookBookMsg: string[] = [];\n\ export const cookBookTag: string[] = [];\n\ \n\ -for( let i = 0; i < 147; i++) {\n\ +for( let i = 0; i < 148; i++) {\n\ cookBookMsg[ i ] = '';\n\ }\n\ "; diff --git a/linter/docs/rules/recipe10.md b/linter/docs/rules/recipe10.md deleted file mode 100644 index cfaa4830f..000000000 --- a/linter/docs/rules/recipe10.md +++ /dev/null @@ -1,31 +0,0 @@ -# ``bigint`` is not a builtin type, suffix ``n`` for numeric literals is not supported - -Rule ``arkts-no-n-suffix`` - -**Severity: error** - -ArkTS supports ``bigint`` as a part of the standard library, not as a builtin -type. ``n`` suffix for numeric literals is not supported, ``BigInt`` factory -function can be used to produce values of ``bigint`` type. - - -## TypeScript - - -``` - - let a: bigint = 1n - -``` - -## ArkTS - - -``` - - let a = BigInt(1) - let b: bigint = BigInt(2) - -``` - - diff --git a/linter/docs/rules/recipe102.md b/linter/docs/rules/recipe102.md index 6776df1b8..598f43ccc 100644 --- a/linter/docs/rules/recipe102.md +++ b/linter/docs/rules/recipe102.md @@ -1,10 +1,10 @@ # Interface declarations (extends same property) -Rule ``arkts-no-extend-same-property`` +Rule ``arkts-no-extend-same-prop`` **Severity: error** -In TypeScript, an interface that extends two other interfaces with the same method, +In TypeScript, an interface that extends two other interfaces with the same method must declare that method with a combined result type. It is not allowed in ArkTS because |LANG| does not allow an interface to contain two methods with signatures that are not distinguishable, e.g., two methods that have the same diff --git a/linter/docs/rules/recipe105.md b/linter/docs/rules/recipe105.md index e7e9d47bd..f68c49d03 100644 --- a/linter/docs/rules/recipe105.md +++ b/linter/docs/rules/recipe105.md @@ -4,11 +4,12 @@ Rule ``arkts-no-prop-existence-check`` **Severity: error** -ArkTS requires that object layout is determined in compile-time and cannot +ArkTS requires that object layout is determined at compile time and cannot be changed at runtime. There for no runtime property-based checks are supported. If you need to do a type cast, use ``as`` operator and use desired properties -and methods. If some property doesn't exist then an attempt to reference it -will result in a compile-time error. +and methods. +If some property does not exist, then an attempt to refer to it results +in a compile-time error. ## TypeScript diff --git a/linter/docs/rules/recipe109.md b/linter/docs/rules/recipe109.md index 05dd754c2..ec6ef7f38 100644 --- a/linter/docs/rules/recipe109.md +++ b/linter/docs/rules/recipe109.md @@ -4,10 +4,10 @@ Rule ``arkts-no-dyn-prop-decl`` **Severity: error** -ArkTS does not support dynamic property declaration. All object properties must -be declared immediately in the class. While it can be replaced with an array -of objects, it is still better to adhere to the static language paradigm and -declare fields, their names and types explicitly. +ArkTS does not support dynamic property declaration. All object properties +must be declared immediately in the class. While it can be replaced with an +array of objects, it is still better to adhere to the static language paradigm +and declare fields, their names and types explicitly. ## TypeScript diff --git a/linter/docs/rules/recipe113.md b/linter/docs/rules/recipe113.md index 26465b677..26a1aa7f5 100644 --- a/linter/docs/rules/recipe113.md +++ b/linter/docs/rules/recipe113.md @@ -4,8 +4,8 @@ Rule ``arkts-no-enum-merging`` **Severity: error** -ArkTS does not support merging declratations for ``enum``. -The declaration of each ``enum`` must be kept compact in the code base. +ArkTS does not support merging declratations for ``enum``. The declaration +of each ``enum`` must be kept compact in the code base. ## TypeScript diff --git a/linter/docs/rules/recipe121.md b/linter/docs/rules/recipe121.md index ef4631c12..ce8d38e80 100644 --- a/linter/docs/rules/recipe121.md +++ b/linter/docs/rules/recipe121.md @@ -4,8 +4,9 @@ Rule ``arkts-no-require`` **Severity: error** -ArkTS does not support importing via ``require``. ``import`` assignment are -not supported either. Use regular ``import`` instead. +ArkTS does not support importing via ``require``. +``import`` assignments are not supported either. +Use regular ``import`` instead. ## TypeScript @@ -31,3 +32,4 @@ not supported either. Use regular ``import`` instead. - Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) + diff --git a/linter/docs/rules/recipe124.md b/linter/docs/rules/recipe124.md deleted file mode 100644 index b1a80dc42..000000000 --- a/linter/docs/rules/recipe124.md +++ /dev/null @@ -1,39 +0,0 @@ -# Export list declaration is not supported - -Rule ``arkts-no-export-list-decl`` - -**Severity: error** - -ArkTS does not support syntax of export list declarations. All exported -entities must be explicitly annotated with the ``export`` keyword. - - -## TypeScript - - -``` - - export { x } - export { x } from "mod" - export { x, y as b, z as c } - -``` - -## ArkTS - - -``` - - let x = 1 - class MyClass {} - export let y = x, z: number = 2 - export RenamedClass = MyClass - -``` - -## See also - -- Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) -- Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) - - diff --git a/linter/docs/rules/recipe125.md b/linter/docs/rules/recipe125.md index 4aa7cec5d..50109740e 100644 --- a/linter/docs/rules/recipe125.md +++ b/linter/docs/rules/recipe125.md @@ -54,7 +54,6 @@ Other syntax flavors like ``export * as ...`` are not supported. ## See also -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) - Recipe 126: ``export = ...`` assignment is not supported (``arkts-no-export-assignment``) diff --git a/linter/docs/rules/recipe126.md b/linter/docs/rules/recipe126.md index 59a9551ca..5e4f7f9af 100644 --- a/linter/docs/rules/recipe126.md +++ b/linter/docs/rules/recipe126.md @@ -49,7 +49,6 @@ Use regular ``export`` / ``import`` instead. ## See also - Recipe 121: ``require`` and ``import`` assignment are not supported (``arkts-no-require``) -- Recipe 124: Export list declaration is not supported (``arkts-no-export-list-decl``) - Recipe 125: Re-exporting is supported with restrictions (``arkts-limited-reexport``) diff --git a/linter/docs/rules/recipe129.md b/linter/docs/rules/recipe129.md index fa5e7dc9e..6d41a927b 100644 --- a/linter/docs/rules/recipe129.md +++ b/linter/docs/rules/recipe129.md @@ -4,8 +4,9 @@ Rule ``arkts-no-module-wildcards`` **Severity: error** -ArkTS does not supported wildcards in module names because in |LANG|, import -is a compile-time, not a runtime feature. Use ordinary export syntax instead. +ArkTS does not support wildcards in module names because in the language +import is a compile-time, not a runtime feature. +Use ordinary export syntax instead. ## TypeScript @@ -13,11 +14,31 @@ is a compile-time, not a runtime feature. Use ordinary export syntax instead. ``` + // Declaration: declare module "*!text" { const content: string export default content } + // Consuming code: + import fileContent from "some.txt!text" + +``` + +## ArkTS + + +``` + + // Declaration: + declare namespace N { + function foo(x: number): number + } + + // Consuming code: + import * from "module" + console.log("N.foo called: ", N.foo(42)) + ``` ## See also diff --git a/linter/docs/rules/recipe130.md b/linter/docs/rules/recipe130.md index 4a5c602e6..b0f094ff9 100644 --- a/linter/docs/rules/recipe130.md +++ b/linter/docs/rules/recipe130.md @@ -4,10 +4,10 @@ Rule ``arkts-no-umd`` **Severity: error** -ArkTS does not support universal module definitions (UMD) because in |LANG| -there is no concept of "script" (as opposed to "module"). Besides, in ArkTS -import is a compile-time, not a runtime feature. Use ordinary syntax for -``export`` and ``import`` instead. +ArkTS does not support universal module definitions (UMD) because in the +language there is no concept of "script" (as opposed to "module"). +Besides, in ArkTS import is a compile-time, not a runtime feature. +Use ordinary syntax for ``export`` and ``import`` instead. ## TypeScript diff --git a/linter/docs/rules/recipe131.md b/linter/docs/rules/recipe131.md index a103967cd..9bd40dd8f 100644 --- a/linter/docs/rules/recipe131.md +++ b/linter/docs/rules/recipe131.md @@ -4,8 +4,8 @@ Rule ``arkts-no-js-extension`` **Severity: error** -ArkTS does not allow to use ``.js`` extension in module identifiers because it -has its own mechanisms for interoperating with JavaScript. +ArkTS does not allow using ``.js`` extension in module identifiers because +it has its own mechanisms for interoperating with JavaScript. ## TypeScript diff --git a/linter/docs/rules/recipe132.md b/linter/docs/rules/recipe132.md index c38299638..517a1c5a6 100644 --- a/linter/docs/rules/recipe132.md +++ b/linter/docs/rules/recipe132.md @@ -26,6 +26,23 @@ to the statically typing. ``` +## ArkTS + + +``` + + class CustomError extends Error { + constructor(message?: string) { + // Call parent's constructor, inheritance chain is static and + // cannot be modified in runtime + super(message) + console.log(this instanceof Error) // true + } + } + let ce = new CustomError() + +``` + ## See also - Recipe 136: Prototype assignment is not supported (``arkts-no-prototype-assignment``) diff --git a/linter/docs/rules/recipe133.md b/linter/docs/rules/recipe133.md index ab2f0a51e..b9c586300 100644 --- a/linter/docs/rules/recipe133.md +++ b/linter/docs/rules/recipe133.md @@ -5,8 +5,8 @@ Rule ``arkts-no-runtime-import`` **Severity: error** ArkTS does not support such "runtime" import expressions as ``await import...`` -because in ArkTS import is a compile-time, not a runtime feature. Use regular -import syntax instead. +because in the language import is a compile-time, not a runtime feature. +Use regular import syntax instead. ## TypeScript diff --git a/linter/docs/rules/recipe134.md b/linter/docs/rules/recipe134.md index 3286e1cbf..60916e809 100644 --- a/linter/docs/rules/recipe134.md +++ b/linter/docs/rules/recipe134.md @@ -5,8 +5,8 @@ Rule ``arkts-no-definite-assignment`` **Severity: error** ArkTS does not support definite assignment assertions ``let v!: T`` because -they are considered an excessive compiler hint. Use declaration with -initialization instead. +they are considered an excessive compiler hint. +Use declaration with initialization instead. ## TypeScript diff --git a/linter/docs/rules/recipe135.md b/linter/docs/rules/recipe135.md index 5e7bb8835..df981900a 100644 --- a/linter/docs/rules/recipe135.md +++ b/linter/docs/rules/recipe135.md @@ -4,9 +4,9 @@ Rule ``arkts-no-iife`` **Severity: error** -ArkTS does not support IIFEs as namespace declarations because in |LANG|, -anonymous functions cannot serve as namespaces. Use regular syntax for -namespaces instead. +ArkTS does not support IIFEs as namespace declarations because anonymous +functions in the language cannot serve as namespaces. +Use regular syntax for namespaces instead. ## TypeScript diff --git a/linter/docs/rules/recipe136.md b/linter/docs/rules/recipe136.md index 550b95b54..231fe3003 100644 --- a/linter/docs/rules/recipe136.md +++ b/linter/docs/rules/recipe136.md @@ -6,7 +6,8 @@ Rule ``arkts-no-prototype-assignment`` 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 the static typing. +applicable to the static typing. Mechanism of classes and / or interfaces +should be used instead to statically "combine" methods to data together. ## TypeScript @@ -14,7 +15,7 @@ applicable to the static typing. ``` - var C = function(p) { + var C = function(p: number) { this.p = p // Compile-time error only with noImplicitThis } @@ -24,8 +25,25 @@ applicable to the static typing. } } - C.prototype.q = function(r) { - return this.p === r + 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 + } } ``` diff --git a/linter/docs/rules/recipe138.md b/linter/docs/rules/recipe138.md index 7dfec46f8..843577939 100644 --- a/linter/docs/rules/recipe138.md +++ b/linter/docs/rules/recipe138.md @@ -8,8 +8,8 @@ Currently ArkTS does not support utility types from TypeScript extensions to the standard library (``Omit``, ``Pick``, etc.). Exceptions are: ``Partial``, ``Record``. -For ``Record`` type, the type of value must be either optional or unioned with -the ``undefined`` type. +For Record type, the type of an indexing expression *rec[index]* is +of * *V | undefined* type. ## TypeScript diff --git a/linter/docs/rules/recipe140.md b/linter/docs/rules/recipe140.md index ae347c437..febf6d055 100644 --- a/linter/docs/rules/recipe140.md +++ b/linter/docs/rules/recipe140.md @@ -4,12 +4,12 @@ Rule ``arkts-no-func-apply-bind-call`` **Severity: error** -ArkTS does not allow to use standard library functions ``Function.apply``, -``Function.bind``, ``Function.call``. These APIs are needed in the standard +ArkTS does not allow using standard library functions ``Function.apply``, +``Function.bind`` and ``Function.call``. These APIs are needed in the standard library to explicitly set ``this`` parameter for the called function. -In ArkTS semantics of ``this`` is restricted to the conventional OOP style, -and usage of ``this`` in stand-alone functions is prohibited. Thus these -functions are excessive. +In ArkTS the semantics of ``this`` is restricted to the conventional OOP +style, and the usage of ``this`` in stand-alone functions is prohibited. +Thus these functions are excessive. ## TypeScript diff --git a/linter/docs/rules/recipe141.md b/linter/docs/rules/recipe141.md index 1e16d75ad..a772b5388 100644 --- a/linter/docs/rules/recipe141.md +++ b/linter/docs/rules/recipe141.md @@ -4,7 +4,7 @@ Rule ``arkts-no-readonly-params`` **Severity: error** -Currently ArkTS supports ``readonly`` for properties, but not for parameters. +Currently, ArkTS supports ``readonly`` for properties, but not for parameters. ## TypeScript diff --git a/linter/docs/rules/recipe143.md b/linter/docs/rules/recipe143.md index 9dbec44af..444ceadb8 100644 --- a/linter/docs/rules/recipe143.md +++ b/linter/docs/rules/recipe143.md @@ -4,7 +4,7 @@ Rule ``arkts-no-import-assertions`` **Severity: error** -ArkTS does not support import assertions because in |LANG|, import is a +ArkTS does not support import assertions because in the language import is a compile-time, not a runtime feature. So asserting correctness of imported APIs in runtime does not make sense for the statically typed language. Use ordinary ``import`` syntax instead. diff --git a/linter/docs/rules/recipe144.md b/linter/docs/rules/recipe144.md index 7a2ed2363..556747f0c 100644 --- a/linter/docs/rules/recipe144.md +++ b/linter/docs/rules/recipe144.md @@ -4,10 +4,10 @@ Rule ``arkts-limited-stdlib`` **Severity: error** -ArkTS does not allow usage of some APIs from the TypeScript/JavaScript standard library. -The most part of the restricted APIs relates to manipulating objects in -dynamic manner, which is not compatible with the static typing. Following APIs -are prohibited from usage: +ArkTS does not allow using some APIs from the TypeScript/JavaScript standard library. +The most part of the restricted APIs relates to manipulating 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``, ``Infinity``, ``NaN``, ``isFinite``, ``isNaN``, ``parseFloat``, ``parseInt``, diff --git a/linter/docs/rules/recipe145.md b/linter/docs/rules/recipe145.md index 022f436ff..92298aae7 100644 --- a/linter/docs/rules/recipe145.md +++ b/linter/docs/rules/recipe145.md @@ -6,7 +6,7 @@ Rule ``arkts-strict-typing`` Type checker in ArkTS is not optional, the code must be explicitly and correctly types to be compiled and run. When porting from the standard TypeScript, -following flags should be turned on: ``noImplicitReturns``, +the following flags must be turned on: ``noImplicitReturns``, ``strictFunctionTypes``, ``strictNullChecks``, ``strictPropertyInitialization``. diff --git a/linter/docs/rules/recipe146.md b/linter/docs/rules/recipe146.md index 6426faf28..c47a215e5 100644 --- a/linter/docs/rules/recipe146.md +++ b/linter/docs/rules/recipe146.md @@ -5,7 +5,7 @@ Rule ``arkts-strict-typing-required`` **Severity: error** Type checker in ArkTS is not optional, the code must be explicitly and -correctly types to be compiled and run. "Suppressing" type checker in-place +correctly typed to be compiled and run. "Suppressing" type checker in-place with special comments is not allowed. In particular, ``@ts-ignore`` and ``@ts-nocheck`` annotations are not supported. diff --git a/linter/docs/rules/recipe147.md b/linter/docs/rules/recipe147.md index de1f456d1..f158e98ef 100644 --- a/linter/docs/rules/recipe147.md +++ b/linter/docs/rules/recipe147.md @@ -4,8 +4,9 @@ Rule ``arkts-no-ts-deps`` **Severity: error** -Code base implemented in the standard TypeScript currently should not depend on ArkTS -through importing ArkTS code base. Imports in reverse direction are supported. +Currently, the code base implemented in the standard TypeScript language must not +depend on ArkTS through importing the |LANG| code base. Imports in reverse +direction are supported. ## TypeScript @@ -21,6 +22,23 @@ through importing ArkTS code base. Imports in reverse direction are supported. // lib.ts import { C } from "app" + +``` + +## ArkTS + + +``` + + // lib1.ets + export class C { + // ... + } + + // lib2.ets + import { C } from "lib1" + + ``` diff --git a/linter/docs/rules/recipe148.md b/linter/docs/rules/recipe148.md new file mode 100644 index 000000000..d17da6816 --- /dev/null +++ b/linter/docs/rules/recipe148.md @@ -0,0 +1,42 @@ +# No decorators except ArkUI decorators are currently allowed + +Rule ``arkts-no-decorators-except-arkui`` + +**Severity: error** + +Currently, only ArkUI decorators are allowed in the ArkTS. +Any other decorator will cause compile-time error. + + +## TypeScript + + +``` + + function classDecorator(x: any, y: any): void { + // + } + + @classDecorator + class BugReport { + } + + +``` + +## ArkTS + + +``` + + function classDecorator(x: any, y: any): void { + // + } + + @classDecorator // compile-time error: unsupported decorator + class BugReport { + } + +``` + + diff --git a/linter/docs/rules/recipe16.md b/linter/docs/rules/recipe16.md index 8fd0da8ee..8e8037fd6 100644 --- a/linter/docs/rules/recipe16.md +++ b/linter/docs/rules/recipe16.md @@ -4,8 +4,8 @@ Rule ``arkts-no-multiple-static-blocks`` **Severity: error** -ArkTS does not allow to have sevaral static block for class initialization, -combine static blocks statements to the one static block. +ArkTS does not allow having sevaral static blocks for class initialization. +Combine static block statements into one static block. ## TypeScript diff --git a/linter/docs/rules/recipe19.md b/linter/docs/rules/recipe19.md index 41baed871..0d36274e5 100644 --- a/linter/docs/rules/recipe19.md +++ b/linter/docs/rules/recipe19.md @@ -4,8 +4,8 @@ Rule ``arkts-no-intersection-types`` **Severity: error** -Currently, ArkTS does not support intersection types. You can use inheritance -as a work-around. +Currently, ArkTS does not support intersection types. Use inheritance +as a workaround. ## TypeScript diff --git a/linter/docs/rules/recipe22.md b/linter/docs/rules/recipe22.md index 1ea9a18cb..9637228b2 100644 --- a/linter/docs/rules/recipe22.md +++ b/linter/docs/rules/recipe22.md @@ -5,8 +5,8 @@ Rule ``arkts-no-conditional-types`` **Severity: error** ArkTS does not support conditional type aliases. Introduce a new type with -constraints explicitly or rewrite logic with use of ``Object``. ``infer`` -keyword is not supported. +constraints explicitly, or rewrite logic using ``Object``. The keyword +``infer`` is not supported. ## TypeScript diff --git a/linter/docs/rules/recipe25.md b/linter/docs/rules/recipe25.md index 035716d5b..8c611cd81 100644 --- a/linter/docs/rules/recipe25.md +++ b/linter/docs/rules/recipe25.md @@ -5,7 +5,7 @@ Rule ``arkts-no-ctor-prop-decls`` **Severity: error** ArkTS does not support declaring class fields in the ``constructor``. -You must declare them inside the ``class`` declaration instead. +Declare class fields inside the ``class`` declaration instead. ## TypeScript diff --git a/linter/docs/rules/recipe27.md b/linter/docs/rules/recipe27.md index 776f84abd..79a314308 100644 --- a/linter/docs/rules/recipe27.md +++ b/linter/docs/rules/recipe27.md @@ -1,4 +1,4 @@ -# Construct signatures not supported in interfaces +# Construct signatures are not supported in interfaces Rule ``arkts-no-ctor-signatures-iface`` diff --git a/linter/docs/rules/recipe3.md b/linter/docs/rules/recipe3.md index 3611a35c2..2c9098805 100644 --- a/linter/docs/rules/recipe3.md +++ b/linter/docs/rules/recipe3.md @@ -4,8 +4,8 @@ Rule ``arkts-no-private-identifiers`` **Severity: error** -ArkTS does not private identifiers started with ``#`` symbol, use ``private`` -keyword instead. +ArkTS does not use private identifiers starting with ``#`` symbol, use +the keyword ``private`` instead. ## TypeScript diff --git a/linter/docs/rules/recipe30.md b/linter/docs/rules/recipe30.md index 78cd9278b..d0a069e36 100644 --- a/linter/docs/rules/recipe30.md +++ b/linter/docs/rules/recipe30.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-identity`` **Severity: error** Currently, ArkTS does not support structural identity, i.e., the compiler -cannot compare two types' public APIs and decide whether such types are +cannot compare public APIs of two types and decide whether such types are identical. Use other mechanisms (inheritance, interfaces or type aliases) instead. diff --git a/linter/docs/rules/recipe31.md b/linter/docs/rules/recipe31.md index bd8337a3c..d2eef94fb 100644 --- a/linter/docs/rules/recipe31.md +++ b/linter/docs/rules/recipe31.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-subtyping`` **Severity: error** Currently, ArkTS does not check structural equivalence for type inference, -i.e., the compiler cannot compare two types' public APIs and decide whether +i.e., the compiler cannot compare public APIs of two types and decide whether such types are identical. Use other mechanisms (inheritance or interfaces) instead. diff --git a/linter/docs/rules/recipe32.md b/linter/docs/rules/recipe32.md index 6bb5251a6..cc7e41628 100644 --- a/linter/docs/rules/recipe32.md +++ b/linter/docs/rules/recipe32.md @@ -5,8 +5,8 @@ Rule ``arkts-no-structural-assignability`` **Severity: error** Currently, ArkTS does not check structural equivalence when checking if types -are assignable to each other, i.e., the compiler cannot compare two types' -public APIs and decide whether such types are identical. Use other mechanisms +are assignable to each other, i.e., the compiler cannot compare public APIs of +two types and decide whether such types are identical. Use other mechanisms (inheritance or interfaces) instead. diff --git a/linter/docs/rules/recipe34.md b/linter/docs/rules/recipe34.md index c1536ee24..3e6b617c3 100644 --- a/linter/docs/rules/recipe34.md +++ b/linter/docs/rules/recipe34.md @@ -5,8 +5,8 @@ Rule ``arkts-no-inferred-generic-params`` **Severity: error** ArkTS allows to omit generic type parameters if it is possible to infer -the concrete types from the parameters passed to the function. Otherwise a -compile-time error occurs. In particular, inference of generic type parameters +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. diff --git a/linter/docs/rules/recipe35.md b/linter/docs/rules/recipe35.md index 0aab3e3bd..9645463e7 100644 --- a/linter/docs/rules/recipe35.md +++ b/linter/docs/rules/recipe35.md @@ -5,7 +5,7 @@ Rule ``arkts-no-structural-inference`` **Severity: error** Currently, ArkTS does not support structural typing, i.e., the compiler cannot -compare two types' public APIs and decide whether such types are identical. +compare public APIs of two types and decide whether such types are identical. Use inheritance and interfaces to specify the relation between the types explicitly. diff --git a/linter/docs/rules/recipe37.md b/linter/docs/rules/recipe37.md index f0ee0385f..862c026b2 100644 --- a/linter/docs/rules/recipe37.md +++ b/linter/docs/rules/recipe37.md @@ -4,8 +4,8 @@ Rule ``arkts-no-regexp-literals`` **Severity: error** -Currently, ArkTS does not support RegExp literals. Use library call with string -literals instead. +Currently, ArkTS does not support RegExp literals. Use library call with +string literals instead. ## TypeScript diff --git a/linter/docs/rules/recipe38.md b/linter/docs/rules/recipe38.md index 62b06f7a9..a0fdb0a06 100644 --- a/linter/docs/rules/recipe38.md +++ b/linter/docs/rules/recipe38.md @@ -5,9 +5,9 @@ Rule ``arkts-no-untyped-obj-literals`` **Severity: error** ArkTS supports usage of object literals if the compiler can infer to what -classes or interfaces such literals correspond to. Otherwise, a compile-time -error occurs. Specifically, using literals to initialize classes and interfaces -is not supported in following contexts: +classes or interfaces such literals correspond to. A compile-time error +occurs otherwise. 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 diff --git a/linter/docs/rules/recipe43.md b/linter/docs/rules/recipe43.md index e7257c77b..b2ee2d200 100644 --- a/linter/docs/rules/recipe43.md +++ b/linter/docs/rules/recipe43.md @@ -5,8 +5,8 @@ Rule ``arkts-no-noninferrable-arr-literals`` **Severity: error** Basically, ArkTS infers the type of an array literal as a union type of its -contents. But if there is at least one element with a non-inferrable type -(e.g. untyped object literal), a compile-time error occurs. +contents. However, a compile-time error occurs if there is at least one +element with a non-inferrable type (e.g. untyped object literal). ## TypeScript diff --git a/linter/docs/rules/recipe46.md b/linter/docs/rules/recipe46.md index 71fcbf8a1..cf1ac5cf3 100644 --- a/linter/docs/rules/recipe46.md +++ b/linter/docs/rules/recipe46.md @@ -4,8 +4,8 @@ Rule ``arkts-no-func-expressions`` **Severity: error** -ArkTS does not support function expressions, use arrow functions instead -to be explicitly specified. +ArkTS does not support function expressions. Use arrow functions instead +to specify explicitly. ## TypeScript diff --git a/linter/docs/rules/recipe50.md b/linter/docs/rules/recipe50.md index 1f839a5e1..cd2738534 100644 --- a/linter/docs/rules/recipe50.md +++ b/linter/docs/rules/recipe50.md @@ -4,8 +4,8 @@ Rule ``arkts-no-class-literals`` **Severity: error** -ArkTS does not support class literals. A new named class type must be -introduced explicitly. +ArkTS does not support class literals. Introduce new named class types +explicitly. ## TypeScript diff --git a/linter/docs/rules/recipe52.md b/linter/docs/rules/recipe52.md index f4ff3fd4b..fd7e53ae8 100644 --- a/linter/docs/rules/recipe52.md +++ b/linter/docs/rules/recipe52.md @@ -6,7 +6,7 @@ Rule ``arkts-no-undefined-prop-access`` ArkTS supports accessing only those class properties that are either declared in the class, or accessible via inheritance. Accessing any other properties is -prohibited and causes compile-time errors. Use proper types to check property +prohibited, and causes compile-time errors. Use proper types to check property existence during compilation. diff --git a/linter/docs/rules/recipe53.md b/linter/docs/rules/recipe53.md index ea6c5a8a1..825fe0f5b 100644 --- a/linter/docs/rules/recipe53.md +++ b/linter/docs/rules/recipe53.md @@ -4,13 +4,12 @@ Rule ``arkts-as-casts`` **Severity: error** -ArkTS supports ``as`` keyword as the only syntax for type casts. +ArkTS supports the keyword ``as`` as the only syntax for type casts. Incorrect cast causes a compile-time error or runtime ``ClassCastException``. ```` syntax for type casts is not supported. -However, if a **primitive** type (e.g. a ``number`` or a ``boolean``) must be -cast to the reference type, this must be done through the ``new ...`` expression -instead of ``as``. +Use the expression ``new ...`` instead of ``as`` if a **primitive** type +(e.g., a ``number`` or a ``boolean``) must be cast to the reference type. ## TypeScript diff --git a/linter/docs/rules/recipe60.md b/linter/docs/rules/recipe60.md index 38b6ca476..0df74f8a6 100644 --- a/linter/docs/rules/recipe60.md +++ b/linter/docs/rules/recipe60.md @@ -4,8 +4,8 @@ Rule ``arkts-no-type-query`` **Severity: error** -ArkTS supports ``typeof`` operator only in the expression context. Specifying -type notations using ``typeof`` is not supported. +ArkTS supports ``typeof`` operator only in the expression context. Using +``typeof`` to specify type notations is not supported. ## TypeScript diff --git a/linter/docs/rules/recipe63.md b/linter/docs/rules/recipe63.md new file mode 100644 index 000000000..dc35085bd --- /dev/null +++ b/linter/docs/rules/recipe63.md @@ -0,0 +1,70 @@ +# Binary ``+`` operator supports implicit casts only for numbers, enums and strings + +Rule ``arkts-no-polymorphic-plus`` + +**Severity: error** + +If one of the operands of binary ``+`` operator is +of the string type (including enum string constant), the other operand +can be of any type, and its value is implicitly converted to string. +Otherwise, ArkTS supports implicit casts for ``+`` only for +numbers and numeric enum constants. +ArkTS as TypeScript does not support ``+`` operator for booleans. +Elsewhere, any form of an explicit cast is required. + + +## TypeScript + + +``` + + enum E { E1, E2 } + + let a = 10 + 32 // 42 + let b = E.E1 + 10 // 10 + let c = 10 + "5" // "105" + + let d = "5" + E.E2 // "51" + let e = "Hello, " + "world!" // "Hello, world!" + let f = "string" + true // "stringtrue" + + let g = (new Object()) + "string" // "[object Object]string" + + let i = true + true // JS: 2, TS: compile-time error + let j = true + 2 // JS: 3, TS: compile-time error + let k = E.E1 + true // JS: 1, TS: compile-time error + + +``` + +## ArkTS + + +``` + + enum E { E1, E2 } + + let a = 10 + 32 // 42 + let b = E.E1 + 10 // 10 + let c = 10 + "5" // "105" + + let d = "5" + E.E2 // "51" + let e = "Hello, " + "world!" // "Hello, world!" + let f = "string" + true // "stringtrue" + + let g = (new Object()).toString() + "string" + + + let i = true + true // compile-time error + let j = true + 2 // compile-time error + let k = E.E1 + true // compile-time error + + +``` + +## See also + +- Recipe 055: Unary operators ``+``, ``-`` and ``~`` work only on numbers (``arkts-no-polymorphic-unops``) + + + diff --git a/linter/docs/rules/recipe66.md b/linter/docs/rules/recipe66.md index 10476f234..20bc3b6bd 100644 --- a/linter/docs/rules/recipe66.md +++ b/linter/docs/rules/recipe66.md @@ -6,7 +6,7 @@ Rule ``arkts-no-in`` ArkTS does not support the ``in`` operator. However, this operator makes little sense since the object layout is known at compile time and cannot -be modified at runtime. Use ``instanceof`` as a work-around if you still need +be modified at runtime. Use ``instanceof`` as a workaround if you still need to check whether certain class members exist. diff --git a/linter/docs/rules/recipe76.md b/linter/docs/rules/recipe76.md index beec4a751..e620ace6b 100644 --- a/linter/docs/rules/recipe76.md +++ b/linter/docs/rules/recipe76.md @@ -4,9 +4,9 @@ Rule ``arkts-no-implied-inference`` **Severity: error** -Currently, ArkTS does not support inference of implied types. Use explicit -type notation instead. Use ``Object[]`` if you need containers that hold -data of mixed types. +Currently, ArkTS does not support inference of implied types. +Use explicit type notation instead. +Use ``Object[]`` if you need containers that hold data of mixed types. ## TypeScript diff --git a/linter/docs/rules/recipe79.md b/linter/docs/rules/recipe79.md index 15f916438..30bcb8dd4 100644 --- a/linter/docs/rules/recipe79.md +++ b/linter/docs/rules/recipe79.md @@ -4,8 +4,8 @@ Rule ``arkts-no-types-in-catch`` **Severity: error** -In TypeScript catch clause variable type annotation must be ``any`` or ``unknown`` -if specified. As ArkTS does not support these types, a type annotation should +In TypeScript, catch clause variable type annotation must be ``any`` or ``unknown`` +if specified. As ArkTS does not support these types, a type annotation must be omitted. diff --git a/linter/docs/rules/recipe8.md b/linter/docs/rules/recipe8.md index 327672363..bd35822de 100644 --- a/linter/docs/rules/recipe8.md +++ b/linter/docs/rules/recipe8.md @@ -4,8 +4,8 @@ Rule ``arkts-no-any-unknown`` **Severity: error** -ArkTS does not support ``any``, and ``unknown`` types. Please specify types -explicitly. +ArkTS does not support the types ``any`` and ``unknown``. Please specify +types explicitly. ## TypeScript diff --git a/linter/docs/rules/recipe80.md b/linter/docs/rules/recipe80.md index 190320e61..5c2b43061 100644 --- a/linter/docs/rules/recipe80.md +++ b/linter/docs/rules/recipe80.md @@ -6,8 +6,9 @@ Rule ``arkts-no-for-in`` ArkTS does not support the 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. For arrays, you can iterate with the regular ``for`` loop. +considered redundant because object layout is known at compile time, and +cannot change at runtime. For arrays, you can iterate with the regular +``for`` loop. ## TypeScript @@ -36,7 +37,7 @@ change at runtime. For arrays, you can iterate with the regular ``for`` loop. ## See also -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) +- Recipe 081: Iterable interfaces are not supported (``arkts-no-iterable``) - Recipe 082: ``for-of`` is supported only for arrays and strings (``arkts-for-of-str-arr``) diff --git a/linter/docs/rules/recipe81.md b/linter/docs/rules/recipe81.md index 226c41097..541ab965a 100644 --- a/linter/docs/rules/recipe81.md +++ b/linter/docs/rules/recipe81.md @@ -1,6 +1,6 @@ # Iterable interfaces are not supported -Rule ``arkts-noiterable`` +Rule ``arkts-no-iterable`` **Severity: error** diff --git a/linter/docs/rules/recipe82.md b/linter/docs/rules/recipe82.md index e6c28d9b6..1c2efa50e 100644 --- a/linter/docs/rules/recipe82.md +++ b/linter/docs/rules/recipe82.md @@ -36,6 +36,6 @@ but does not support the iteration of objects content. ## See also - Recipe 080: ``for .. in`` is not supported (``arkts-no-for-in``) -- Recipe 081: Iterable interfaces are not supported (``arkts-noiterable``) +- Recipe 081: Iterable interfaces are not supported (``arkts-no-iterable``) diff --git a/linter/docs/rules/recipe84.md b/linter/docs/rules/recipe84.md index b0e6a2752..f5d6f4bcb 100644 --- a/linter/docs/rules/recipe84.md +++ b/linter/docs/rules/recipe84.md @@ -8,4 +8,26 @@ ArkTS does not support the ``with`` statement. Use other language idioms (including fully qualified names of functions) to achieve the same behaviour. +## TypeScript + + +``` + + with (Math) { // Compile-time error, but JavaScript code still emitted + let r: number = 42 + console.log("Area: ", PI * r * r) + } + +``` + +## ArkTS + + +``` + + let r: number = 42 + console.log("Area: ", Math.PI * r * r) + +``` + diff --git a/linter/docs/rules/recipe99.md b/linter/docs/rules/recipe99.md index 23349a239..f0145e2cf 100644 --- a/linter/docs/rules/recipe99.md +++ b/linter/docs/rules/recipe99.md @@ -5,7 +5,7 @@ Rule ``arkts-no-spread`` **Severity: error** The only supported scenario for the spread operator is to spread an array into -the rest parameter. Otherwise manually "unpack" data from arrays and objects, +the rest parameter. Otherwise, manually "unpack" data from arrays and objects, where necessary. diff --git a/linter/src/CookBookMsg.ts b/linter/src/CookBookMsg.ts index 50cf78a1b..cd0a4c973 100644 --- a/linter/src/CookBookMsg.ts +++ b/linter/src/CookBookMsg.ts @@ -16,7 +16,7 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; -for( let i = 0; i < 147; i++) { +for( let i = 0; i < 148; i++) { cookBookMsg[ i ] = ''; } @@ -29,7 +29,7 @@ cookBookTag[ 6 ] = ''; cookBookTag[ 7 ] = ''; cookBookTag[ 8 ] = 'Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)'; cookBookTag[ 9 ] = ''; -cookBookTag[ 10 ] = '"bigint" is not a builtin type, suffix "n" for numeric literals is not supported (arkts-no-n-suffix)'; +cookBookTag[ 10 ] = ''; cookBookTag[ 11 ] = ''; cookBookTag[ 12 ] = ''; cookBookTag[ 13 ] = 'Use "Object[]" instead of tuples (arkts-no-tuples)'; @@ -46,7 +46,7 @@ cookBookTag[ 23 ] = ''; cookBookTag[ 24 ] = ''; cookBookTag[ 25 ] = 'Declaring fields in "constructor" is not supported (arkts-no-ctor-prop-decls)'; cookBookTag[ 26 ] = ''; -cookBookTag[ 27 ] = 'Construct signatures not supported in interfaces (arkts-no-ctor-signatures-iface)'; +cookBookTag[ 27 ] = 'Construct signatures are not supported in interfaces (arkts-no-ctor-signatures-iface)'; cookBookTag[ 28 ] = 'Indexed access types are not supported (arkts-no-aliases-by-index)'; cookBookTag[ 29 ] = 'Indexed access is not supported for fields (arkts-no-props-by-index)'; cookBookTag[ 30 ] = 'Structural identity is not supported (arkts-no-structural-identity)'; @@ -82,7 +82,7 @@ cookBookTag[ 59 ] = '"delete" operator is not supported (arkts-no-delete)'; cookBookTag[ 60 ] = '"typeof" operator is allowed only in expression contexts (arkts-no-type-query)'; cookBookTag[ 61 ] = ''; cookBookTag[ 62 ] = ''; -cookBookTag[ 63 ] = ''; +cookBookTag[ 63 ] = 'Binary "+" operator supports implicit casts only for numbers, enums and strings (arkts-no-polymorphic-plus)'; cookBookTag[ 64 ] = ''; cookBookTag[ 65 ] = '"instanceof" operator is partially supported (arkts-instanceof-ref-types)'; cookBookTag[ 66 ] = '"in" operator is not supported (arkts-no-in)'; @@ -100,7 +100,7 @@ cookBookTag[ 77 ] = ''; cookBookTag[ 78 ] = ''; cookBookTag[ 79 ] = 'Type annotation in catch clause is not supported (arkts-no-types-in-catch)'; cookBookTag[ 80 ] = '"for .. in" is not supported (arkts-no-for-in)'; -cookBookTag[ 81 ] = 'Iterable interfaces are not supported (arkts-noiterable)'; +cookBookTag[ 81 ] = 'Iterable interfaces are not supported (arkts-no-iterable)'; cookBookTag[ 82 ] = '"for-of" is supported only for arrays and strings (arkts-for-of-str-arr)'; cookBookTag[ 83 ] = 'Mapped type expression is not supported (arkts-no-mapped-types)'; cookBookTag[ 84 ] = '"with" statement is not supported (arkts-no-with)'; @@ -121,7 +121,7 @@ cookBookTag[ 98 ] = ''; cookBookTag[ 99 ] = 'It is possible to spread only arrays into the rest parameter (arkts-no-spread)'; cookBookTag[ 100 ] = ''; cookBookTag[ 101 ] = ''; -cookBookTag[ 102 ] = 'Interface declarations (extends same property) (arkts-no-extend-same-property)'; +cookBookTag[ 102 ] = 'Interface declarations (extends same property) (arkts-no-extend-same-prop)'; cookBookTag[ 103 ] = 'Declaration merging is not supported (arkts-no-decl-merging)'; cookBookTag[ 104 ] = 'Interfaces cannot extend classes (arkts-extends-only-class)'; cookBookTag[ 105 ] = 'Property-based runtime type checks are not supported (arkts-no-prop-existence-check)'; @@ -143,7 +143,7 @@ cookBookTag[ 120 ] = '"import default as ..." is not supported (arkts-no-import- cookBookTag[ 121 ] = '"require" and "import" assignment are not supported (arkts-no-require)'; cookBookTag[ 122 ] = ''; cookBookTag[ 123 ] = ''; -cookBookTag[ 124 ] = 'Export list declaration is not supported (arkts-no-export-list-decl)'; +cookBookTag[ 124 ] = ''; cookBookTag[ 125 ] = 'Re-exporting is supported with restrictions (arkts-limited-reexport)'; cookBookTag[ 126 ] = '"export = ..." assignment is not supported (arkts-no-export-assignment)'; cookBookTag[ 127 ] = 'Special "export type" declarations are not supported (arkts-no-special-exports)'; @@ -167,3 +167,4 @@ cookBookTag[ 144 ] = 'Usage of standard library is restricted (arkts-limited-std cookBookTag[ 145 ] = 'Strict type checking is enforced (arkts-strict-typing)'; cookBookTag[ 146 ] = 'Switching off type checks with in-place comments is not allowed (arkts-strict-typing-required)'; cookBookTag[ 147 ] = 'No dependencies on TypeScript code are currently allowed (arkts-no-ts-deps)'; +cookBookTag[ 148 ] = 'No decorators except ArkUI decorators are currently allowed (arkts-no-decorators-except-arkui)'; diff --git a/linter/src/Problems.ts b/linter/src/Problems.ts index 59b83bace..707937f4d 100644 --- a/linter/src/Problems.ts +++ b/linter/src/Problems.ts @@ -19,7 +19,7 @@ export enum FaultID { DestructuringParameter, YieldExpression, InterfaceOrEnumMerging, InterfaceExtendsClass, IndexMember, WithStatement, ThrowStatement, IndexedAccessType, UnknownType, ForInStatement, InOperator, KeyOfOperator, ImportFromPath, FunctionExpression, IntersectionType, - ObjectTypeLiteral, AddWithWrongType, BitOpWithWrongType, CommaOperator, LimitedReturnTypeInference, + ObjectTypeLiteral, AddWithWrongType, CommaOperator, LimitedReturnTypeInference, ArrowFunctionWithOmittedTypes, LambdaWithTypeParameters, ClassExpression, DestructuringAssignment, DestructuringDeclaration, ForOfNonArray, VarDeclaration, CatchWithUnsupportedType, DeleteOperator, DeclWithDuplicateName, UnaryArithmNotNumber, ConstructorType, CallSignature, @@ -82,7 +82,7 @@ faultsAttrs[FaultID.JsxElement] = {cookBookRef: '54',}; faultsAttrs[FaultID.UnaryArithmNotNumber] = {cookBookRef: '55',}; faultsAttrs[FaultID.DeleteOperator] = {cookBookRef: '59',}; faultsAttrs[FaultID.TypeQuery] = {cookBookRef: '60',}; -faultsAttrs[FaultID.BitOpWithWrongType] = {cookBookRef: '61',}; +// remove as rule#61: FaultID.BitOpWithWrongType => {cookBookRef: '61',}; faultsAttrs[FaultID.AddWithWrongType] = {cookBookRef: '63',}; faultsAttrs[FaultID.InstanceofUnsupported] = {cookBookRef: '65',}; faultsAttrs[FaultID.InOperator] = {cookBookRef: '66',}; diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index bfc3b80dc..df1df74d1 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -870,11 +870,19 @@ export class TypeScriptLinter { let rightOperandType = this.tsTypeChecker.getTypeAtLocation(tsRhsExpr); if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.PlusToken) { - if (this.tsUtils.isNumberType(leftOperandType) && this.tsUtils.isNumberType(rightOperandType)) + if (this.tsUtils.isEnumMemberType(leftOperandType) && this.tsUtils.isEnumMemberType(rightOperandType)) { + if ( + ( (leftOperandType.getFlags() & (ts.TypeFlags.NumberLike)) && (rightOperandType.getFlags() & (ts.TypeFlags.NumberLike ) ) ) || + ( (leftOperandType.getFlags() & (ts.TypeFlags.StringLike)) && (rightOperandType.getFlags() & (ts.TypeFlags.StringLike ) ) ) + ) + return; + else + this.incrementCounters(node, FaultID.AddWithWrongType); + } else if (this.tsUtils.isNumberType(leftOperandType) && this.tsUtils.isNumberType(rightOperandType)) return; else if (this.tsUtils.isStringType(leftOperandType) || this.tsUtils.isStringType(rightOperandType)) return; - else + else this.incrementCounters(node, FaultID.AddWithWrongType); } else if ( tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.AmpersandToken || @@ -888,7 +896,7 @@ export class TypeScriptLinter { ( tsLhsExpr.kind === ts.SyntaxKind.NumericLiteral && !this.tsUtils.isIntegerConstantValue(tsLhsExpr as ts.NumericLiteral)) || ( tsRhsExpr.kind === ts.SyntaxKind.NumericLiteral && !this.tsUtils.isIntegerConstantValue(tsRhsExpr as ts.NumericLiteral)) ) - this.incrementCounters(node, FaultID.BitOpWithWrongType); + return; // FaultID.BitOpWithWrongType -removed as rule #61 } else if (tsBinaryExpr.operatorToken.kind === ts.SyntaxKind.CommaToken) { // CommaOpertor is allowed in 'for' statement initalizer and incrementor let tsExprNode: ts.Node = tsBinaryExpr; diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 80bdfb332..98ee66d33 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -59,7 +59,7 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.IntersectionType] = 'intersection types and type literals'; LinterConfig.nodeDesc[FaultID.ObjectTypeLiteral] = 'Object type literals'; LinterConfig.nodeDesc[FaultID.AddWithWrongType] = 'binary "+" with wrong operand'; - LinterConfig.nodeDesc[FaultID.BitOpWithWrongType] = 'bit operation with wrong operand'; + // LinterConfig.nodeDesc[FaultID.BitOpWithWrongType] = 'bit operation with wrong operand'; LinterConfig.nodeDesc[FaultID.CommaOperator] = 'comma operator'; LinterConfig.nodeDesc[FaultID.LimitedReturnTypeInference] = 'Functions with limited return type inference'; LinterConfig.nodeDesc[FaultID.ArrowFunctionWithOmittedTypes] = 'Arrow functions with omitted parameter types'; diff --git a/linter/src/Utils.ts b/linter/src/Utils.ts index a68b45db5..c65ba12fd 100644 --- a/linter/src/Utils.ts +++ b/linter/src/Utils.ts @@ -213,6 +213,12 @@ export class TsUtils { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.Enum) !== 0; } + public isEnumMemberType(tsType: ts.Type): boolean { + // Note: For some reason, test (tsType.flags & ts.TypeFlags.Enum) != 0 doesn't work here. + // Must use SymbolFlags to figure out if this is an enum type. + return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.EnumMember) !== 0; + } + public isObjectLiteralType(tsType: ts.Type): boolean { return tsType.symbol && (tsType.symbol.flags & ts.SymbolFlags.ObjectLiteral) !== 0; } diff --git a/linter/test/binary_wrong_types.ts b/linter/test/binary_wrong_types.ts index e62f9d37c..d34dc7b1c 100644 --- a/linter/test/binary_wrong_types.ts +++ b/linter/test/binary_wrong_types.ts @@ -104,3 +104,12 @@ const b42 = 2 | 5.5; const b43 = 5.5 | b42; const b44 = 4 ^ 5.5; const b45 = 5.5 ^ b44; + + +let e1 = Const.PI + Const.E; // OK +let e2 = State.FAULT + State.OK; // OK +let e3 = "State: " + State.FAULT; // OK +let e4 = "Const = " + Const.PI; // OK + +let f1 = Const.PI + State.FAULT; // Error +let f2 = State.OK + Const.E; // Error diff --git a/linter/test/binary_wrong_types.ts.relax.json b/linter/test/binary_wrong_types.ts.relax.json index f5197b0ef..85286d415 100644 --- a/linter/test/binary_wrong_types.ts.relax.json +++ b/linter/test/binary_wrong_types.ts.relax.json @@ -44,130 +44,20 @@ "column": 3, "problem": "EnumMemberNonConstInit" }, - { - "line": 59, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 60, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 61, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 63, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 64, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 65, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 67, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 68, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 69, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 83, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 84, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 85, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 87, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 88, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 89, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 91, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 92, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 93, - "column": 13, - "problem": "BitOpWithWrongType" - }, { "line": 95, "column": 15, "problem": "CommaOperator" }, { - "line": 101, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 102, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 103, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 104, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 105, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 114, + "column": 10, + "problem": "AddWithWrongType" }, { - "line": 106, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 115, + "column": 10, + "problem": "AddWithWrongType" } ] } \ No newline at end of file diff --git a/linter/test/binary_wrong_types.ts.strict.json b/linter/test/binary_wrong_types.ts.strict.json index f5197b0ef..85286d415 100644 --- a/linter/test/binary_wrong_types.ts.strict.json +++ b/linter/test/binary_wrong_types.ts.strict.json @@ -44,130 +44,20 @@ "column": 3, "problem": "EnumMemberNonConstInit" }, - { - "line": 59, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 60, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 61, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 63, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 64, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 65, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 67, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 68, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 69, - "column": 12, - "problem": "BitOpWithWrongType" - }, - { - "line": 83, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 84, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 85, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 87, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 88, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 89, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 91, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 92, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 93, - "column": 13, - "problem": "BitOpWithWrongType" - }, { "line": 95, "column": 15, "problem": "CommaOperator" }, { - "line": 101, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 102, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 103, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 104, - "column": 13, - "problem": "BitOpWithWrongType" - }, - { - "line": 105, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 114, + "column": 10, + "problem": "AddWithWrongType" }, { - "line": 106, - "column": 13, - "problem": "BitOpWithWrongType" + "line": 115, + "column": 10, + "problem": "AddWithWrongType" } ] } \ No newline at end of file diff --git a/linter/test/instanceof.ts.relax.json b/linter/test/instanceof.ts.relax.json index f9d548166..cec2272db 100644 --- a/linter/test/instanceof.ts.relax.json +++ b/linter/test/instanceof.ts.relax.json @@ -24,11 +24,6 @@ "column": 11, "problem": "InstanceofUnsupported" }, - { - "line": 28, - "column": 12, - "problem": "BitOpWithWrongType" - }, { "line": 30, "column": 11, diff --git a/linter/test/instanceof.ts.strict.json b/linter/test/instanceof.ts.strict.json index d95a4cf33..e3679adf5 100644 --- a/linter/test/instanceof.ts.strict.json +++ b/linter/test/instanceof.ts.strict.json @@ -24,11 +24,6 @@ "column": 11, "problem": "InstanceofUnsupported" }, - { - "line": 28, - "column": 12, - "problem": "BitOpWithWrongType" - }, { "line": 30, "column": 11, -- Gitee From a05d032a0e5597fba74f1bfc22b96d952067c971 Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Mon, 31 Jul 2023 17:18:31 +0300 Subject: [PATCH 4/9] [ArkTS Linter] Relax rule #125: Limited re-export declaration support. Change-Id: I0486a5fc5e0ff5e4795a747b3cea730d67ef7b3b Signed-off-by: Evgeniy Okolnov --- linter/src/TypeScriptLinter.ts | 2 +- linter/src/TypeScriptLinterConfig.ts | 2 +- linter/test/modules.ts | 5 ++++- linter/test/modules.ts.autofix.json | 14 +++++++------- linter/test/modules.ts.relax.json | 12 ++++++------ linter/test/modules.ts.strict.json | 14 +++++++------- 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index df1df74d1..ef5117fee 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -1267,7 +1267,7 @@ export class TypeScriptLinter { this.incrementCounters(node, FaultID.TypeOnlyExport, true, autofix); } - if (tsExportDecl.moduleSpecifier) + if (tsExportDecl.moduleSpecifier && !tsExportDecl.exportClause) this.incrementCounters(node, FaultID.ReExporting); let exportClause = tsExportDecl.exportClause; diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index 98ee66d33..b3b2ec9a3 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -99,7 +99,7 @@ export class LinterConfig { LinterConfig.nodeDesc[FaultID.TypeOnlyExport] = 'Type-only exports'; LinterConfig.nodeDesc[FaultID.DefaultImport] = 'Default import declarations'; LinterConfig.nodeDesc[FaultID.ExportListDeclaration] = 'Export list declarations'; - LinterConfig.nodeDesc[FaultID.ReExporting] = 'Re-exporting declarations'; + LinterConfig.nodeDesc[FaultID.ReExporting] = 'Limited re-exporting declarations'; LinterConfig.nodeDesc[FaultID.ExportAssignment] = 'Export assignments (export = ..)'; LinterConfig.nodeDesc[FaultID.ImportAssignment] = 'Import assignments (import = ..)'; LinterConfig.nodeDesc[FaultID.PropertyRuntimeCheck] = 'Property-based runtime checks'; diff --git a/linter/test/modules.ts b/linter/test/modules.ts index 9cb59c813..7be759af2 100644 --- a/linter/test/modules.ts +++ b/linter/test/modules.ts @@ -102,7 +102,10 @@ export { SomeClass as AnotherClass }; // Export renaming export { Foo, Bar as Baz, Goo as Zar }; // Export list declaration -export { SomeFunction } from 'module'; // Re-exporting +// Re-exporting +export * from 'module1'; // Not supported +export * as Utilities from 'module2'; // Ok +export { SomeFunction, SomeType as OtherType } from 'module3'; // Ok class Point {} export = Point; diff --git a/linter/test/modules.ts.autofix.json b/linter/test/modules.ts.autofix.json index fbb25f5c2..c93d13bcd 100755 --- a/linter/test/modules.ts.autofix.json +++ b/linter/test/modules.ts.autofix.json @@ -208,43 +208,43 @@ "autofixable": false }, { - "line": 105, + "line": 106, "column": 1, "problem": "ReExporting", "autofixable": false }, { - "line": 105, + "line": 108, "column": 8, "problem": "ExportListDeclaration", "autofixable": false }, { - "line": 108, + "line": 111, "column": 1, "problem": "ExportAssignment", "autofixable": false }, { - "line": 110, + "line": 113, "column": 1, "problem": "ImportAssignment", "autofixable": false }, { - "line": 111, + "line": 114, "column": 1, "problem": "ImportAssignment", "autofixable": false }, { - "line": 113, + "line": 116, "column": 5, "problem": "ImportAssignment", "autofixable": false }, { - "line": 114, + "line": 117, "column": 7, "problem": "ImportAssignment", "autofixable": false diff --git a/linter/test/modules.ts.relax.json b/linter/test/modules.ts.relax.json index cf6083c3a..1076677a3 100644 --- a/linter/test/modules.ts.relax.json +++ b/linter/test/modules.ts.relax.json @@ -75,32 +75,32 @@ "problem": "NamespaceAsObject" }, { - "line": 105, + "line": 106, "column": 1, "problem": "ReExporting" }, { - "line": 108, + "line": 111, "column": 1, "problem": "ExportAssignment" }, { - "line": 110, + "line": 113, "column": 1, "problem": "ImportAssignment" }, { - "line": 111, + "line": 114, "column": 1, "problem": "ImportAssignment" }, { - "line": 113, + "line": 116, "column": 5, "problem": "ImportAssignment" }, { - "line": 114, + "line": 117, "column": 7, "problem": "ImportAssignment" } diff --git a/linter/test/modules.ts.strict.json b/linter/test/modules.ts.strict.json index 899f9cd50..5d55dc61f 100644 --- a/linter/test/modules.ts.strict.json +++ b/linter/test/modules.ts.strict.json @@ -135,37 +135,37 @@ "problem": "ExportListDeclaration" }, { - "line": 105, + "line": 106, "column": 1, "problem": "ReExporting" }, { - "line": 105, + "line": 108, "column": 8, "problem": "ExportListDeclaration" }, { - "line": 108, + "line": 111, "column": 1, "problem": "ExportAssignment" }, { - "line": 110, + "line": 113, "column": 1, "problem": "ImportAssignment" }, { - "line": 111, + "line": 114, "column": 1, "problem": "ImportAssignment" }, { - "line": 113, + "line": 116, "column": 5, "problem": "ImportAssignment" }, { - "line": 114, + "line": 117, "column": 7, "problem": "ImportAssignment" } -- Gitee From d0a76736aafdf11c5a85f36664115d7268131bfe Mon Sep 17 00:00:00 2001 From: Evgeniy Okolnov Date: Fri, 4 Aug 2023 00:11:55 +0300 Subject: [PATCH 5/9] [ArkTS Linter] Relax rule #138: Allow usage of Partial and Record with certain restrictions. Change-Id: I2a13b1d367e07bb10d1756067b27babfcc611935 Signed-off-by: Evgeniy Okolnov --- linter/src/TypeScriptLinter.ts | 40 +++- linter/src/TypeScriptLinterConfig.ts | 7 - linter/src/Utils.ts | 41 +++- linter/test/func_def_params.ts | 30 --- linter/test/func_def_params.ts.autofix.skip | 0 linter/test/func_def_params.ts.relax.json | 17 -- linter/test/func_def_params.ts.strict.json | 17 -- linter/test/interfaces_optional_props.ts | 29 --- .../interfaces_optional_props.ts.autofix.skip | 0 .../interfaces_optional_props.ts.relax.json | 17 -- .../interfaces_optional_props.ts.strict.json | 17 -- linter/test/object_literals_2.ts | 39 +++- linter/test/object_literals_2.ts.relax.json | 24 +-- linter/test/object_literals_2.ts.strict.json | 34 +-- linter/test/utility_types.ts | 44 ++-- linter/test/utility_types.ts.relax.json | 187 ++++++++-------- linter/test/utility_types.ts.strict.json | 201 +++++++++--------- 17 files changed, 351 insertions(+), 393 deletions(-) delete mode 100644 linter/test/func_def_params.ts delete mode 100644 linter/test/func_def_params.ts.autofix.skip delete mode 100644 linter/test/func_def_params.ts.relax.json delete mode 100644 linter/test/func_def_params.ts.strict.json delete mode 100644 linter/test/interfaces_optional_props.ts delete mode 100644 linter/test/interfaces_optional_props.ts.autofix.skip delete mode 100644 linter/test/interfaces_optional_props.ts.relax.json delete mode 100644 linter/test/interfaces_optional_props.ts.strict.json diff --git a/linter/src/TypeScriptLinter.ts b/linter/src/TypeScriptLinter.ts index ef5117fee..b745331ed 100644 --- a/linter/src/TypeScriptLinter.ts +++ b/linter/src/TypeScriptLinter.ts @@ -626,13 +626,21 @@ export class TypeScriptLinter { let propName = (node as ts.PropertyAssignment | ts.PropertyDeclaration).name; if (propName && (propName.kind === ts.SyntaxKind.NumericLiteral || propName.kind === ts.SyntaxKind.StringLiteral)) { - let autofix : Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); - let autofixable = autofix != undefined; - if (!this.autofixesInfo.shouldAutofix(node, FaultID.LiteralAsPropertyName)) { - autofix = undefined; + // We can use literals as property names only when creating Record instances. + let isRecordObjectInitializer = false; + if (ts.isPropertyAssignment(node)) { + let objectLiteralType = this.tsTypeChecker.getContextualType(node.parent); + isRecordObjectInitializer = !!objectLiteralType && this.tsUtils.isStdRecordType(objectLiteralType); } - this.incrementCounters(node, FaultID.LiteralAsPropertyName, autofixable, autofix); + if (!isRecordObjectInitializer) { + let autofix : Autofix[] | undefined = Autofixer.fixLiteralAsPropertyName(node); + let autofixable = autofix != undefined; + if (!this.autofixesInfo.shouldAutofix(node, FaultID.LiteralAsPropertyName)) { + autofix = undefined; + } + this.incrementCounters(node, FaultID.LiteralAsPropertyName, autofixable, autofix); + } } // Filter out non-initializable property decorators from strict diagnostics. @@ -1447,8 +1455,28 @@ export class TypeScriptLinter { private handleTypeReference(node: ts.Node) { let typeRef = node as ts.TypeReferenceNode; - if (ts.isIdentifier(typeRef.typeName) && LinterConfig.standardUtilityTypes.has(typeRef.typeName.text)) + if (ts.isIdentifier(typeRef.typeName) && TsUtils.LIMITED_STANDARD_UTILITY_TYPES.includes(typeRef.typeName.text)) this.incrementCounters(node, FaultID.UtilityType); + + // Using Record type is allowed only when its value type is optional (i.e. "T | undefined"). + const type = this.tsTypeChecker.getTypeFromTypeNode(typeRef); + if (this.tsUtils.isStdRecordType(type)) { + let isValidTypeArg = false; + if (typeRef.typeArguments && typeRef.typeArguments.length === 2) { + let recordValueType = this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[1]); + if (recordValueType && this.tsUtils.isNullableUnionType(recordValueType)) isValidTypeArg = true; + } + if (!isValidTypeArg) this.incrementCounters(node, FaultID.UtilityType); + } + // Using Partial type is allowed only when its argument type is either Class or Interface. + else if ( + ts.isIdentifier(typeRef.typeName) && typeRef.typeName.text === 'Partial' && + typeRef.typeArguments && typeRef.typeArguments.length === 1 + ) { + let argType = this.tsTypeChecker.getTypeFromTypeNode(typeRef.typeArguments[0]); + if (!argType || !argType.isClassOrInterface()) + this.incrementCounters(node, FaultID.UtilityType); + } } private handleMetaProperty(node: ts.Node) { diff --git a/linter/src/TypeScriptLinterConfig.ts b/linter/src/TypeScriptLinterConfig.ts index b3b2ec9a3..5b899c162 100644 --- a/linter/src/TypeScriptLinterConfig.ts +++ b/linter/src/TypeScriptLinterConfig.ts @@ -144,13 +144,6 @@ export class LinterConfig { } } - // currently utility types from TypeScript extensions are not supported - static standardUtilityTypes: Set = new Set([ - 'Awaited', 'Partial', 'Required', 'Readonly', 'Record', 'Pick', 'Omit', 'Exclude', 'Extract', 'NonNullable', - 'Parameters', 'ConstructorParameters', 'ReturnType', 'InstanceType', 'ThisParameterType', 'OmitThisParameter', - 'ThisType', 'Uppercase', 'Lowercase', 'Capitalize', 'Uncapitalize', - ]); - // must detect terminals during parsing static terminalTokens: Set = new Set([ ts.SyntaxKind.OpenBraceToken, ts.SyntaxKind.CloseBraceToken, ts.SyntaxKind.OpenParenToken, diff --git a/linter/src/Utils.ts b/linter/src/Utils.ts index c65ba12fd..28f96791a 100644 --- a/linter/src/Utils.ts +++ b/linter/src/Utils.ts @@ -116,6 +116,12 @@ export class TsUtils { static PROPERTY_HAS_NO_INITIALIZER_ERROR_CODE = 2564; + static LIMITED_STANDARD_UTILITY_TYPES = [ + 'Awaited', 'Required', 'Readonly', 'Pick', 'Omit', 'Exclude', 'Extract', 'NonNullable', 'Parameters', + 'ConstructorParameters', 'ReturnType', 'InstanceType', 'ThisParameterType', 'OmitThisParameter', + 'ThisType', 'Uppercase', 'Lowercase', 'Capitalize', 'Uncapitalize', + ]; + constructor(private tsTypeChecker: ts.TypeChecker) { } @@ -337,6 +343,18 @@ export class TsUtils { (tsType.flags & ts.TypeFlags.Intersection) !== 0) ); } + + public isNullableUnionType(type: ts.Type): boolean { + if (type.isUnion()) { + let unionTypes = type.types; + return ( + unionTypes.length === 2 && + ((unionTypes[0].flags & ts.TypeFlags.Undefined) !== 0 || (unionTypes[1].flags & ts.TypeFlags.Undefined) !== 0) + ); + } + + return false; + } public isFunctionOrMethod(tsSymbol: ts.Symbol | undefined): boolean { return ( @@ -646,7 +664,18 @@ export class TsUtils { if (this.areTypesAssignable(compType, rhsExpr)) return true; } } - + + // Allow initializing Record objects with object initializer. + if (this.isStdRecordType(lhsType)) return true; + + // For Partial type, validate its argument type. + if (this.isStdPartialType(lhsType)) { + if (lhsType.aliasTypeArguments && lhsType.aliasTypeArguments.length === 1) + lhsType = lhsType.aliasTypeArguments[0]; + else + return false; + } + if (lhsType.isClassOrInterface()) { if (!ts.isObjectLiteralExpression(rhsExpr)) return false; @@ -772,4 +801,14 @@ export class TsUtils { ? (nodeOrComment as ts.CommentRange).end : (nodeOrComment as ts.Node).getEnd(); } + + public isStdRecordType(type: ts.Type): boolean { + const sym = type.aliasSymbol; + return !!sym && sym.getName() === 'Record' && this.isGlobalSymbol(sym); + } + + public isStdPartialType(type: ts.Type): boolean { + const sym = type.aliasSymbol; + return !!sym && sym.getName() === 'Partial' && this.isGlobalSymbol(sym); + } } diff --git a/linter/test/func_def_params.ts b/linter/test/func_def_params.ts deleted file mode 100644 index 20a310eed..000000000 --- a/linter/test/func_def_params.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -function foo(arg?: number) { - return arg; -} - -function bar(x?: string, y?: number, z?: boolean) { - return 3; -} - -function baz(a?: Number, b?: Boolean, c?: Object) { - return 3; -} - -function ff(a: number, s: string, x: boolean) { - return s; -} diff --git a/linter/test/func_def_params.ts.autofix.skip b/linter/test/func_def_params.ts.autofix.skip deleted file mode 100644 index e69de29bb..000000000 diff --git a/linter/test/func_def_params.ts.relax.json b/linter/test/func_def_params.ts.relax.json deleted file mode 100644 index b06227021..000000000 --- a/linter/test/func_def_params.ts.relax.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2022-2023 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "nodes": [] -} \ No newline at end of file diff --git a/linter/test/func_def_params.ts.strict.json b/linter/test/func_def_params.ts.strict.json deleted file mode 100644 index b06227021..000000000 --- a/linter/test/func_def_params.ts.strict.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2022-2023 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "nodes": [] -} \ No newline at end of file diff --git a/linter/test/interfaces_optional_props.ts b/linter/test/interfaces_optional_props.ts deleted file mode 100644 index 3b718173b..000000000 --- a/linter/test/interfaces_optional_props.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -interface CompilerOptions { - strict?: boolean; - sourcePath?: string; - targetPath?: string; -} - -const options: CompilerOptions = { - strict: true, - sourcePath: './src', -}; - -console.log(options); - -if (options.targetPath == undefined) console.log("'targetPath' is not defined"); diff --git a/linter/test/interfaces_optional_props.ts.autofix.skip b/linter/test/interfaces_optional_props.ts.autofix.skip deleted file mode 100644 index e69de29bb..000000000 diff --git a/linter/test/interfaces_optional_props.ts.relax.json b/linter/test/interfaces_optional_props.ts.relax.json deleted file mode 100644 index e7d2d6779..000000000 --- a/linter/test/interfaces_optional_props.ts.relax.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2023-2023 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "nodes": [] -} \ No newline at end of file diff --git a/linter/test/interfaces_optional_props.ts.strict.json b/linter/test/interfaces_optional_props.ts.strict.json deleted file mode 100644 index e7d2d6779..000000000 --- a/linter/test/interfaces_optional_props.ts.strict.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "copyright": [ - "Copyright (c) 2023-2023 Huawei Device Co., Ltd.", - "Licensed under the Apache License, Version 2.0 (the 'License');", - "you may not use this file except in compliance with the License.", - "You may obtain a copy of the License at", - "", - "http://www.apache.org/licenses/LICENSE-2.0", - "", - "Unless required by applicable law or agreed to in writing, software", - "distributed under the License is distributed on an 'AS IS' BASIS,", - "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.", - "See the License for the specific language governing permissions and", - "limitations under the License." - ], - "nodes": [] -} \ No newline at end of file diff --git a/linter/test/object_literals_2.ts b/linter/test/object_literals_2.ts index 06aed1a84..7960117c0 100644 --- a/linter/test/object_literals_2.ts +++ b/linter/test/object_literals_2.ts @@ -53,12 +53,6 @@ let d: D = { } } -// Special case: initializing of records: -let m1: Record = { - 'a': 33, - 'b': 44 -} - // Restrictions of classes that can be initialized with literal // Default initializable class. class C1 { @@ -166,4 +160,35 @@ interface CompilerOptions { const options: CompilerOptions = { // OK, as 'targetPath' field is optional strict: true, sourcePath: './src', -}; \ No newline at end of file +}; + +// Special case: initializing Record +let m1: Record = { + 'a': 33, + 'b': 44 +}; + +class Person { + name: string = "" + age: number = 0 + location: string = "" +} + +type OptionalPerson = Person | undefined; +let persons : Record = { + "Alice": { name: "Alice", age: 32, location: "Shanghai" }, + "Bob": { name: "Bob", age: 48, location: "New York" } +}; +let persons2 : Record = { + "Alice": { name: "Alice", age: 32, location: "Shanghai" }, + "Bob": { name: "Bob", age: 48, location: "New York" } +}; + +// Special case: initializing Partial +interface Style { + color: number; +} + +function applyStyle(arg: Partial