1# TypeScript and JavaScript Coding Style Guide 2 3# Overview 4 5## Purpose 6 7This guide is applicable to the scenario where TypeScript and JavaScript are used during OpenHarmony application development. 8 9Based on the technical features of language engines and OpenHarmony, as well as industry standards and practices, this guide provides coding guide for improving code standardization, security, and performance. 10 11## Source 12 13This guide is developed based on the *JavaScript Coding Style Guide* [1]. It integrates the technical features of OpenHarmony without violating industry rules, including ESLint and TSC configuration. 14 15The correct and incorrect examples, marked with **@typescript-eslint**, in ESLint rules come from ESLint Rules [2]. 16 17## Document Structure 18 19- [OpenHarmony Application Environment Restrictions](#openharmony-application-environment-restrictions) 20 21 All the restrictions provided in this section are raised for security purposes and therefore are mandatory. 22 23- Programming language features: [Declaration and Initialization](#declaration-and-initialization), [Data Types](#data-types), [Operation and Expressions](#operation-and-expressions), [Functions](#functions), [Classes and Objects](#classes-and-objects), and [Exceptions](#exceptions), [Async Functions](#async-functions), and [Types](#types). 24 25## Conventions 26 27**Rule**: a convention that must be complied with 28 29**Recommendation**: a convention that must be taken into consideration 30 31It is necessary to understand the reason for each rule or recommendation and try to comply with them. 32 33# OpenHarmony Application Environment Restrictions 34 35## Use Strict Mode 36 37**[Category] Rule** 38 39**[Description]** 40 41Strict mode is a way to opt in to a restricted variant of JavaScript, thereby implicitly opting out of sloppy mode. Strict mode is introduced in ECMAScript 5 and enabled by using the **use strict** syntax.) 42 431. Strict mode eliminates some JavaScript silent errors by throwing errors. 441. Strict mode fixes defects that make it difficult for JavaScript engines to perform optimizations. Sometimes, the same code can run faster in strict mode than in non-strict mode. 451. Strict mode prohibits some syntax that may be defined in future versions of ECMAScript. 46 47**Note: Currently, only TypeScript or JavaScript code in strict mode is supported on OpenHarmony ArkCompiler.** 48 49## Do Not Use eval() 50 51**[Category] Rule** 52 53**[Description]** 54 55Using **eval()** causes code disorder and poor readability. 56 57**[Incorrect Example]** 58 59```javascript 60console.log (eval ({ a:2 })); // Output [object Object]. 61console.log(eval('"a" + 2')); // Output 'a2'. 62console.log(eval('{a: 2}')); // Output 2. 63console.log(eval('let value = 1 + 1;'); // Output undefined. 64``` 65 66## Do Not Use with() {} 67 68**[Category] Rule** 69 70**[Description]** 71 72Using **with()** makes the code semantically unclear because the object of **with()** may conflict with local variables, changing the original semantics. 73 74**[Incorrect Example]** 75 76```javascript 77const foo = { x: 5 }; 78with (foo) { 79 let x = 3; 80 console.log(x); // x = 3 81} 82console.log(foo.x); // x = 3 83``` 84 85## Do Not Dynamically Create Functions 86 87**[Category] Rule** 88 89**[Description]** 90 91A function can be defined in three ways: declaration, constructor, and expression. No matter which means is used, the function created is an instance of the **Function** object and inherits all default or custom methods and attributes of the **Function** object. Defining a function by using a constructor is similar to the using of **eval()**. The constructor accepts any string as the function body, causing security vulnerabilities. 92 93**[Incorrect Example]** 94 95```javascript 96let add = new Function('a','b','return a + b'); 97// The function constructor can have only one parameter, which can be any string. 98let dd = new Function('alert("hello")'); 99``` 100 101**[Correct Example]** 102 103```javascript 104// Function declaration. 105function add(a,b){ 106 return a+b; 107} 108// Function expression. 109let add = function(a,b){ 110 return a+b; 111} 112``` 113 114# Declaration and Initialization 115 116## Use const or let Instead of var to Declare Variables 117 118**[Category] Rule** 119 120**[Description]** 121 122ECMAScript 6 allows the use of the **let** and **const** keywords to declare variables in the block scope instead of the function scope. The block scope is commonly used in many programming languages. It is helpful in preventing errors. Use **const** to define read-only variables, and use **let** to define other variables. 123 124**[Incorrect Example]** 125 126```javascript 127var number = 1; 128var count = 1; 129if (isOK) { 130 count += 1; 131} 132``` 133 134**[Correct Example]** 135 136```javascript 137const number = 1; 138let count = 1; 139if (isOK) { 140 count += 1; 141} 142``` 143 144# Data Types 145 146## Do Not Omit 0s Before and After the Decimal Point of a Floating-Point Number 147 148**[Category] Rule** 149 150**[Description]** 151 152In JavaScript, a floating-point number must contain a decimal point, but no digit is required before or after the decimal point. This makes it difficult to distinguish between the decimal point and the dot operator. For this reason, you must use a digit before and after the decimal point for a floating-point number in OpenHarmony code. 153 154**[Incorrect Example]** 155 156```javascript 157const num = .5; 158const num = 2.; 159const num = -.7; 160``` 161 162**[Correct Example]** 163 164```javascript 165const num = 0.5; 166const num = 2.0; 167const num = -0.7; 168``` 169 170## Use isNaN() to Check Whether a Variable Is NaN 171 172**[Category] Rule** 173 174**[Description]** 175 176In JavaScript, NaN is a particular value of a numeric data type. It represents a non-numeric value in the double-precision 64-bit format, as defined in the IEEE floating-point standard. 177NaN is unique in JavaScript because it is not equal to any value, including itself. Therefore, the result of comparison with NaN is confusing, as the values of **NaN !== NaN** and **NaN != NaN** are both **true**. 178Therefore, you must use **Number.isNaN()** or the global **isNaN()** function to check whether a variable is NaN. 179 180**[Incorrect Example]** 181 182```javascript 183if (foo == NaN) { 184 // ... 185} 186if (foo != NaN) { 187 // ... 188} 189``` 190 191**[Correct Example]** 192 193```javascript 194if (isNaN(foo)) { 195 // ... 196} 197if (!isNaN(foo)) { 198 // ... 199} 200``` 201 202## Do Not Use == or === to Check Whether Floating-Point Numbers Are Equal 203 204**[Category] Rule** 205 206**[Description]** 207 208Due to the precision problem, mathematically equal numbers may not be equal in floating-point arithmetic. Therefore, the equality operators **==** and **===** cannot be used to check whether floating-point numbers are equal. 209 210**[Incorrect Example]** 211 212```javascript 2130.1 + 0.2 == 0.3; // false 2140.1 + 0.2 === 0.3; // false 215``` 216 217**[Correct Example]** 218 219```javascript 220const EPSILON = 1e-6; 221const num1 = 0.1; 222const num2 = 0.2; 223const sum = 0.3; 224if(Math.abs(num1 + num2 - sum) < EPSILON) { 225 ... 226} 227``` 228 229## Do Not Define or Use Non-numeric Attributes (Except Length) for Arrays 230 231**[Category] Rule** 232 233**[Description]** 234 235In JavaScript, an array is an object, which can be added with attributes. To facilitate processing and avoid errors, use an array to store only a group of ordered data, that is, data with continuous indexes. If attributes must be added, use **Map** or **Object** instead. 236 237**[Incorrect Example]** 238 239```javascript 240const myHash = []; 241myHash['key1'] = 'val1'; 242myHash['key2'] = 'val2'; 243myHash[0] = '222'; 244for (const key in myHash) { 245 // The value of key is 0, key1, and key2. 246 console.log(key); 247} 248console.log(myHash.length); // The array length is 1. 249``` 250 251**[Correct Example]** 252 253Use Map and Object for non-numeric attributes. 254 255```javascript 256const map = new Map(); 257map.set('key1', 'val1'); 258map.set('key2', 'val2'); 259for(const [key, value] of map) { 260 console.log('Attribute:' + key +', value: '+ value); 261} 262``` 263 264## Preferentially Use Array Object Methods for Array Traversal 265 266**[Category] Rule** 267 268**[Description]** 269 270To traverse an array, preferentially use the methods provided by **Array**, such as **forEach()**, **map()**, **every()**, **filter()**, **find()**, **findIndex()**, **reduce()**, and **some()**. 271Do not use **for in** to traverse an array. 272 273**[Incorrect Example]** 274 275```javascript 276const numbers = [1, 2, 3, 4, 5]; 277let sum = 0; 278// Use for in to traverse the array. 279for (const num in numbers) { 280 console.log(num); 281 sum += num; 282} 283// Use for to traverse an existing array to generate a new array. 284const increasedByOne = []; 285for (let i = 0; i < numbers.length; i++) { 286 increasedByOne.push(numbers[i] + 1); 287} 288``` 289 290**[Correct Example]** 291 292```javascript 293const numbers = [1, 2, 3, 4, 5]; 294// Use for of to traverse the array and obtain the sum. 295let sum = 0; 296for (const num of numbers) { 297 sum += num; 298} 299// Use forEach to traverse the array and obtain the sum. 300let sum = 0; 301numbers.forEach(num => sum += num); 302// Better: Use the reduce method to obtain the sum. 303const sum = numbers.reduce((total, num) => total + num, 0); 304// Use forEach to traverse an existing array to generate a new array. 305const increasedByOne = []; 306numbers.forEach(num => increasedByOne.push(num + 1)); 307// Better: Use the map method. 308const increasedByOne = numbers.map(num => num + 1); 309``` 310 311# Operation and Expressions 312 313## Use === and !==, Instead of == or !=, to Check Whether the Operands Are Equal 314 315**[Category] Rule** 316 317**[Description]** 318 319In JavaScript, type conversion is automatically performed when the **==** operator is used for equality judgment. For example, the values of **[] == false**, **[] == ![]**, and **3 == '03'** are **true**. For higher efficiency, use **===** in comparison when the type is determined. 320 321**[Incorrect Example]** 322 323```javascript 324age == bee 325foo == true 326bananas != 1 327value == undefined 328typeof foo == 'undefined' 329'hello' != 'world' 3300 == 0 331true == true 332``` 333 334**[Correct Example]** 335 336```javascript 337age === bee 338foo === true 339bananas !== 1 340value === undefined 341typeof foo === 'undefined' 342'hello' !== 'world' 3430 === 0 344true === true 345``` 346 347**[Exceptions]** 348 349```javascript 350// Use the following to determine whether an object is null: 351obj == null 352obj != null 353``` 354 355## Do Not Assign Values in Control Conditional Expressions 356 357**[Category] Rule** 358 359**[Description]** 360 361Control conditional expressions are usually used in conditional statements such as **if**, **while**, **for**, and **?:**. 362Assigning values in this type of expression often leads to unexpected behavior and poor code readability. 363 364**[Incorrect Example]** 365 366```javascript 367// It is difficult to understand the value assignment in the control conditional expression. 368if (isFoo = false) { 369 ... 370} 371``` 372 373**[Correct Example]** 374 375```javascript 376const isFoo = someBoolean; // Assign a value above and directly use it in the if statement. 377if (isFoo) { 378 ... 379} 380``` 381 382# Functions 383 384## Use the Same Return Statement 385 386**[Category] Rule** 387 388**[Description]** 389 390Unlike statically typed languages that force a function to return a value of a specified type, JavaScript allows different code paths in a function to return different types of values. 391 392JavaScript returns **undefined** in the following cases: 393 3941. The **return** statement is not executed before the exit. 3951. The **return** statement is executed, but no value is explicitly assigned. 3961. The **return undefined** statement is executed. 3971. The **return void** statement is executed, followed by an expression (for example, a function call). 3981. The **return** statement is executed, followed by another expression equivalent to **undefined**. 399 400In a function (especially in a larger function), if any code path explicitly returns a value but the other code paths do not explicitly return a value, this may be a coding error. Therefore, use the same **return** statement in a function. 401 402**[Incorrect Example]** 403 404```javascript 405function doSomething(condition) { 406 if (condition) { 407 ... 408 return true; 409 } else { 410 ... 411 return; 412 } 413} 414function doSomething(condition) { 415 if (condition) { 416 ... 417 return true; 418 } 419} 420``` 421 422**[Correct Example]** 423 424```javascript 425// Ensure that all paths return values in the same way. 426function doSomething(condition) { 427 if (condition) { 428 ... 429 return true; 430 } else { 431 ... 432 return false; 433 } 434} 435 436function doSomething(condition) { 437 if (condition) { 438 ... 439 return true; 440 } 441 ... 442 return false; 443} 444``` 445 446## Use rest Instead of arguments 447 448**[Category] Rule** 449 450**[Description]** 451 452The **rest** parameter is an array, and all array methods, such as **sort**, **map**, **forEach**, and **pop**, can be directly used on it. **arguments** is a class array. Therefore, use the **rest** syntax instead of **arguments**. In addition, place the **rest** parameter as the last parameter in the list. 453 454**[Incorrect Example]** 455 456```javascript 457function concatenateAll() { 458 // arguments is a class array, and the join method can be used only after arguments is converted to a real array. 459 const args = Array.prototype.slice.call(arguments); 460 return args.join(''); 461} 462``` 463 464**[Correct Example]** 465 466```javascript 467function concatenateAll(...args) { 468 return args.join(''); 469} 470``` 471 472## Do Not Assign this to a Variable; Use this in a Scope 473 474**[Category] Rule** 475 476**[Description]** 477 478Arrow functions provide a simpler syntax. **this** in an arrow function points to the object when it is defined. Assigning **this** to a variable is confusing. 479 480**[Incorrect Example]** 481 482```javascript 483function foo() { 484 const self = this; 485 return function() { 486 console.log(self); 487 }; 488} 489``` 490 491**[Correct Example]** 492 493```javascript 494function foo() { 495 return () => { 496 console.log(this); 497 }; 498} 499``` 500 501For details, see [@typescript-eslint/no-this-alias](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-this-alias.md). 502 503The description of ESLint is stricter. Therefore, do not assign **this** to a variable in any case. 504 505# Classes and Objects 506 507## Use Dots to Access Object Attributes and [] to Access Computed Attributes 508 509**[Category] Rule** 510 511**[Description]** 512 513In JavaScript, you can use dots (**foo.bar**) or square brackets (**foo['bar']**) to access attributes. The use of dots is preferred because it is more readable, concise, and more suitable for JavaScript compression. 514 515**[Correct Example]** 516 517```javascript 518const name = obj.name; 519const key = getKeyFromDB(); 520const prop = obj[key]; // Use [] only when the attribute name is a variable. 521``` 522 523## Do Not Modify the Prototype of a Built-in Object or Add Methods to the Prototype 524 525**[Category] Rule** 526 527**[Description]** 528 529As a set of public interfaces, built-in objects have conventional behavior modes. Any modification to the prototype of a built-in object may damage the semantics. Therefore, never modify the prototype of a built-in object, or add methods to the prototype. 530 531**[Incorrect Example]** 532 533```javascript 534Array.prototype.indexOf = function () { 535 return -1; 536} 537// Used in other places. 538const arr = [1, 1, 1, 1, 1, 2, 1, 1, 1]; 539console.log (arr.indexOf(2)); // Output -1. 540``` 541 542## Do Not Delete the Computed Attributes of an Object 543 544**[Category] Rule** 545 546**[Description]** 547 548The delete operation changes the layout of an object. Deleting the computed attributes of an object is a dangerous behavior. It greatly restricts the runtime optimization and affects the execution performance. 549 550You are advised not to delete any attribute of an object. If necessary, use **map** and **set**. 551 552**[Incorrect Example]** 553 554```javascript 555// Can be replaced with the constant equivalents, such as container.aaa 556delete container['aaa']; 557 558// Dynamic, difficult-to-reason-about lookups 559const name = 'name'; 560delete container[name]; 561delete container[name.toUpperCase()]; 562``` 563 564**[Correct Example]** 565 566```javascript 567// The code affects the optimization performance to some extent, but it is better than deleting the computed attributes. 568delete container.aaa; 569 570delete container[7]; 571``` 572 573For details, see [@typescript-eslint/no-dynamic-delete](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-dynamic-delete.md). 574 575# Exceptions 576 577## Do Not Use return, break, continue, or throw to End the Finally Block Abnormally 578 579**[Category] Rule** 580 581**[Description]** 582 583In the finally block, if the **return**, **break**, **continue**, or **throw** statement is directly used or the exception that occurs during the method calling is not handled, the finally block ends abnormally. Such a block affects the throwing of exceptions in the **try** or **catch** block, or even the return value of the method. Therefore, you must ensure that the finally block ends normally. 584 585**[Incorrect Example]** 586 587```javascript 588function foo() { 589 try { 590 ... 591 return 1; 592 } catch(err) { 593 ... 594 return 2; 595 } finally { 596 return 3; 597 } 598} 599``` 600 601**[Correct Example]** 602 603```javascript 604function foo() { 605 try { 606 ... 607 return 1; 608 } catch(err) { 609 ... 610 return 2; 611 } finally { 612 console.log('XXX!'); 613 } 614} 615``` 616 617# Async Functions 618 619## Use return await Only When Necessary 620 621**[Category] Rule** 622 623**[Description]** 624 625The return value of an async function is always encapsulated in **Promise.resolve**. The **return await** statement does not actually do anything, but adds time before **Promise.resolve** or **reject**. Therefore, use **return await** only in the **try** or **catch** statement to capture errors of another promise-based function. 626 627**[Incorrect Example]** 628 629```javascript 630async function foo() { 631 return await bar(); 632} 633``` 634 635**[Correct Example]** 636 637```javascript 638async function foo() { 639 return bar(); 640} 641async function foo() { 642 await bar(); 643 return; 644} 645async function foo() { 646 const baz = await bar(); 647 return baz; 648} 649async function foo() { 650 try { 651 return await bar(); 652 } catch (error) { 653 // here can be executed, go on 654 } 655} 656``` 657 658## Do Not Wait for a Non-thenable Value 659 660**[Category] Rule** 661 662**[Description]** 663 664**await** converts a non-thenable value to a promise that has been processed normally and waits for the processing result. In this case, the use of **await** affects the code performance. 665 666**[Incorrect Example]** 667 668```javascript 669async function f3() { 670 const y = await 20; 671 console.log(y); // 20 672} 673 674f3(); 675console.log(30); 676 677// output 678// 30 679// 20 680``` 681 682**[Correct Example]** 683 684```javascript 685async function f3() { 686 const y = 20; 687 console.log(y); // 20 688} 689 690f3(); 691console.log(30); 692 693// output 694// 20 695// 30 696``` 697 698For details, see [@typescript-eslint/await-thenable](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/await-thenable.md). 699 700# Types 701 702## Forcibly Mark null and undefined as Independent Types 703 704**[Category] Rule** 705 706**[Description]** 707 708Marking **null** and **undefined** as independent types improves code security and avoids null pointer exceptions. 709 710**[Incorrect Example]** 711 712```javascript 713let userName: string; 714userName = 'hello'; 715userName = undefined; 716``` 717 718**[Correct Example]** 719 720```javascript 721let userName: string | undefined; 722userName = 'hello'; 723userName = undefined; 724``` 725 726## Explicitly Declare the Return Value Types of Functions and Class Methods 727 728**[Category] Rule** 729 730**[Description]** 731 732Explicitly declare the return value type to ensure that the return value is assigned to the variable of the correct type. In addition, the explicit declaration ensures that **undefined** is not assigned to a variable when there is no return value. 733 734**[Incorrect Example]** 735 736```javascript 737// When there is no return value, the return value type is not declared as void. 738function test() { 739 return; 740} 741// The return value type is not declared as number. 742function fn() { 743 return 1; 744}; 745// The return value type is not declared as string. 746let arrowFn = () => 'test'; 747class Test { 748 // When there is no return value, the return value type is not declared as void. 749 method() { 750 return; 751 } 752} 753``` 754 755**[Correct Example]** 756 757```javascript 758// When there is no return value, explicitly declare the return value type as void. 759function test(): void { 760 return; 761} 762// Explicitly declare the return value type as number. 763function fn(): number { 764 return 1; 765}; 766// Explicitly declare the return value type as string. 767let arrowFn = (): string => 'test'; 768class Test { 769 // When there is no return value, explicitly declare the return value type as void. 770 method(): void { 771 return; 772 } 773} 774``` 775 776For details, see [@typescript-eslint/explicit-function-return-type](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/explicit-function-return-type.md). 777 778## Use Consistent Export Types 779 780**[Category] Rule** 781 782**[Description]** 783 784To export a type, write the type to export and the objects to export separately. 785 786**[Incorrect Example]** 787 788```javascript 789interface ButtonProps { 790 onClick: () => void; 791} 792class Button implements ButtonProps { 793 onClick() { 794 console.log('button!'); 795 } 796} 797export { Button, ButtonProps }; 798``` 799 800**[Correct Example]** 801 802```javascript 803interface ButtonProps { 804 onClick: () => void; 805} 806class Button implements ButtonProps { 807 onClick() { 808 console.log('button!'); 809 } 810} 811export { Button }; 812export type { ButtonProps }; 813``` 814 815For details, see [@typescript-eslint/consistent-type-exports](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/consistent-type-exports.md). 816 817## Use Consistent Import Types 818 819**[Category] Rule** 820 821**[Description]** 822 823To import a type, write the type to import and the objects to import separately. 824 825**[Incorrect Example]** 826 827```javascript 828import { Foo } from 'Foo'; 829import Bar from 'Bar'; 830type T = Foo; 831const x: Bar = 1; 832``` 833 834**[Correct Example]** 835 836```javascript 837import type { Foo } from 'Foo'; 838import type Bar from 'Bar'; 839type T = Foo; 840const x: Bar = 1; 841``` 842 843For details, see [@typescript-eslint/consistent-type-imports](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/consistent-type-imports.md). 844 845## Do Not Use any 846 847**[Category] Rule** 848 849**[Description]** 850 851If the **any** type is used, all type checks during compilation are ignored. This behavior is not necessary and does not meet expectations. If the type is unknown, use **unknown**. 852If the introduced third-party component does not use TypeScript or does not provide the TypeScript type declaration, you can use **any** to declare the related third-party component objects. 853 854## Do Not Define the any Type 855 856**[Category] Rule** 857 858**[Description]** 859 860Do not define the **any** type. This restriction makes types as clear as possible in TypeScript and helps the runtime optimization. 861 862**[Incorrect Example]** 863 864```javascript 865const age: any = 'seventeen'; 866function greet(): any {} 867function greet(param: Array<any>): string {} 868``` 869 870**[Correct Example]** 871 872```javascript 873const age: number = 17; 874function greet(): string {} 875function greet(param: Array<string>): string {} 876``` 877 878For details, see [@typescript-eslint/no-explicit-any](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-explicit-any.md). 879 880## Do Not Pass In any as a Parameter 881 882**[Category] Rule** 883 884**[Incorrect Example]** 885 886```javascript 887declare function foo(arg1: string, arg2: number, arg3: string): void; 888 889const anyTyped = 1 as any; 890 891foo(...anyTyped); 892foo(anyTyped, 1, 'a'); 893 894const tuple1 = ['a', anyTyped, 'b'] as const; 895foo(...tuple1); 896``` 897 898**[Correct Example]** 899 900```javascript 901declare function foo(arg1: string, arg2: number, arg3: string): void; 902 903foo('a', 1, 'b'); 904 905const tuple1 = ['a', 1, 'b'] as const; 906foo(...tuple1); 907``` 908 909For details, see [@typescript-eslint/no-unsafe-argument](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unsafe-argument.md). 910 911## Do Not Use any in Value Assignment 912 913**[Category] Rule** 914 915**[Incorrect Example]** 916 917```javascript 918const x = 1 as any, 919 920const x: Set<string> = new Set<any>(); 921``` 922 923**[Correct Example]** 924 925```javascript 926const x = 1; 927 928const x: Set<string> = new Set<string>(); 929``` 930 931For details, see [@typescript-eslint/no-unsafe-assignment](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unsafe-assignment.md). 932 933## Do Not Call a Variable with the any Type 934 935**[Category] Rule** 936 937**[Incorrect Example]** 938 939```javascript 940declare const anyVar: any; 941declare const nestedAny: { prop: any }; 942 943anyVar(); 944anyVar.a.b(); 945 946nestedAny.prop(); 947nestedAny.prop['a'](); 948``` 949 950**[Correct Example]** 951 952```javascript 953declare const typedVar: () => void; 954declare const typedNested: { prop: { a: () => void } }; 955 956typedVar(); 957typedNested.prop.a(); 958``` 959 960For details, see [@typescript-eslint/no-unsafe-call](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unsafe-call.md). 961 962## Do Not Access Members of an Object with the any Type 963 964**[Category] Rule** 965 966**[Incorrect Example]** 967 968```markup 969declare const anyVar: any; 970declare const nestedAny: { prop: any }; 971 972anyVar.a; 973anyVar.a.b; 974 975nestedAny.prop.a; 976nestedAny.prop['a']; 977``` 978 979**[Correct Example]** 980 981```javascript 982declare const properlyTyped: { prop: { a: string } }; 983 984properlyTyped.prop.a; 985properlyTyped.prop['a']; 986``` 987 988For details, see [@typescript-eslint/no-unsafe-member-access](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unsafe-member-access.md). 989 990## Do Not Declare the Return Value Type of a Function as any or any[] 991 992**[Category] Rule** 993 994**[Incorrect Example]** 995 996```javascript 997function foo1() { 998 return 1 as any; 999} 1000``` 1001 1002**[Correct Example]** 1003 1004```javascript 1005function foo1() : number { 1006 return 1; 1007} 1008``` 1009 1010For details, see [@typescript-eslint/no-unsafe-return](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unsafe-return.md). 1011 1012# References 1013 10141. [JavaScript Coding Style Guide](OpenHarmony-JavaScript-coding-style-guide.md) 10151. [ESLint Rules](https://github.com/typescript-eslint/typescript-eslint/tree/main/packages/eslint-plugin/docs/rules) 10161. High Performance JavaScript 1017