Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Latest commit

 

History

History
297 lines (208 loc) · 5.68 KB

typescript.md

File metadata and controls

297 lines (208 loc) · 5.68 KB

TypeScript Code Style

Table of Contents

General

This style guide extends existing JavaScript style guide and defines rules for TypeScript specific features.

↑ back to TOC

Compiler Options

tsc has some options to make type checks stricter:

{
    "compilerOptions": {
        "strict": true,
        "noEmitOnError": true
    }
}

It's recommended to turn them on as early as possible in development (and migration from JS).

If you want TypeScript to check for unused variables and parameters instead tslint, you can add the following options:

{
    "compilerOptions": {
        "noUnusedLocals": true,
        "noUnusedParameters": true
    }
}

↑ back to TOC

Naming

  • InterfaceLikeThis.

  • TypeAliasLikeThis.

  • In generics:

    • K and V are reserved for key-value generic data structures, K for key types and V for value types;
    • T and U are reserved for generic data types;
    • other generic parameters should have meaningful names:

    Good:

    function foo<Attribute, State>(attributes: Attribute[], state: State): void {
        // ...
    }

    Bad:

    function foo<A, S>(attributes: A[], state: S): void {
        // ...
    }

↑ back to TOC

Typing

  • Prefer interfaces to in place structure definitions:

    Explanation: In place structure definitions make it unnecessary difficult to reuse a type. Also meaningful type names help to document code.

    Good:

    interface Person {
        name: string;
        age: number;
    }
    
    let person: Person;

    Bad:

    let person: {name: string, age: number};
  • Prefer interfaces to type aliases.

    Explanation: From handbook:

    ...interfaces create a new name that is used everywhere... [whereas] ...type aliases don’t create a new name — for instance, error messages won’t use the alias name.

    ...type aliases cannot be extended or implemented from.

  • Don't use void for functions returning undefined:

    Explanation:

    • void means that a function doesn't return a value;
    • void isn't assignable to undefined.

    Good:

    function find(): object | undefined {
        // ...
        return; // or `return undefined;` for the sake of being explicit.
    }

    Bad:

    function find(): object | void {
        // ...
    }
  • There should be one whitespace before and after the type operator:

    Good:

    let foo: string | number;

    Bad:

    let foo: string|number;

↑ back to TOC

Type assertions

  • Use as Type for type assertions:

    Explanation: Use one style for JSX and not.

    Good:

    (someValue as string).length;

    Bad:

    (<string>someValue).length;

Arrays

  • For array declaration use T[] notation:

    Good:

    let pool: (LockableConnection | null)[];

    Bad:

    let pool: Array<LockableConnection | null>;

↑ back to TOC

Classes

  • Don't use public modifier for public class members:

    Explanation: In TypeScript, each member is public by default (like in JavaScript). Explicit public modifier is redundant.

    Good:

    class Foo {
        publicProp: number;
    
        publicMethod(): void {}
    }

    Bad:

    class Foo {
        public publicProp: number;
    
        public publicMethod(): void {}
    }
  • Prefix private and protected fields with _:

    Explanation:

    • Underscore specifies visual difference from public fields. So, you don't need to read the field's declaration to determine its visibility.
    • Minimizes name conflicts with public fields: after adding public field with the same name as private field, you don't need perform renaming.
    • Simplifies migration from JavaScript, where _ often means that the field is "internal".
    • Improves autocompletion by dictionary: when you type _ the autocomplete popup shows non-public fields.

    Good:

    class Foo {
        private _prop: number;
    
        protected _method(): void {}
    }

    Bad:

    class Foo {
        private prop: number;
    
        protected method(): void {}
    }

↑ back to TOC

Enums

  • Prefer using const enums.

    Explanation: const enums are completely removed during compilation. Const enum members are inlined at places of use.

    If you need real objects in generated code, use non-const enums. E.g.:

    • enum contains computed members;
    • enum should be printed (generated object stores both forward (name -> value) and reverse (value -> name) mappings);
    • enum should be available from JavaScript.

↑ back to TOC

  • For enum values use UPPER_CASE style.

    Good:

    enum Foo {
        BAR,
        BAZ
    }
    
    enum Bar {
        FOO = 'foo',
        BAZ = 'baz'
    }

    Bad:

    enum Foo {
        Bar,
        Baz
    }

↑ back to TOC