Skip to content

Angular-RU/angular-style-guide

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Angular / TypeScript projects style guide

TypeScript + ESLint


TypeScript + ESLint

Require that member overloads be consecutive

Use '@typescript-eslint/adjacent-overload-signatures': 'error', because grouping overloaded members together can improve readability of the code.

#f03c15 Bad pattern

class Foo {
    foo(s: string): void;
    foo(n: number): void;
    bar(): void {}
    foo(sn: string | number): void {}
}

export function foo(s: string): void;
export function foo(n: number): void;
export function bar(): void;
export function foo(sn: string | number): void;

#c5f015 Good pattern

class Foo {
    foo(s: string): void;
    foo(n: number): void;
    foo(sn: string | number): void {}
    bar(): void {}
}

export function bar(): void;
export function foo(s: string): void;
export function foo(n: number): void;
export function foo(sn: string | number): void;

Requires using either T[] or Array<T> for arrays

Use '@typescript-eslint/array-type': 'error' for always using T[] or readonly T[] for all array types.

#f03c15 Bad pattern

const x: Array<string> = ['a', 'b'];
const y: ReadonlyArray<string> = ['a', 'b'];

#c5f015 Good pattern

const x: string[] = ['a', 'b'];
const y: readonly string[] = ['a', 'b'];

Disallows awaiting a value that is not a Thenable

Use '@typescript-eslint/await-thenable': 'error'

#f03c15 Bad pattern

await 'value';

const createValue = () => 'value';
await createValue();

#c5f015 Good pattern

await Promise.resolve('value');

const createValue = async () => 'value';
await createValue();

Requires type annotations to exist

Many believe that requiring type annotations unnecessarily can be cumbersome to maintain and generally reduces code readability. TypeScript is often better at inferring types than easily written type annotations would allow. And many people believe instead of enabling typedef, it is generally recommended using the --noImplicitAny and --strictPropertyInitialization compiler options to enforce type annotations only when useful. This rule can enforce type annotations in locations regardless of whether they're required.

But why is annotation description useful? Because for the code review, you will not be able to find out what will change in runtime due to inferred types. But when you specify types, you know exactly what to change to:

It is also worth noting that if we do not use type annotations for methods, it may be difficult for us to read the code during the review, we may not notice something and not pay attention to how the data type has changed if the build does not crash with an error.

Reference to explicit-module-boundary-types

Require explicit return and argument types on exported functions' and classes' public class methods

Explicit types for function return values and arguments makes it clear to any calling code what is the module boundary's input and output.

#f03c15 Bad pattern

// Should indicate that a number is returned
export function myFn() {
    return 1;
}

#c5f015 Good pattern

// A return value of type number
export function myFn(): number {
    return 1;
}

About

Angular / TypeScript projects style guide

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published