Coder Social home page Coder Social logo

typescript's Introduction

Promob TypeScript Style Guide

Style Guide baseado no Airbnb JavaScript Style Guide

Conteúdos

  1. Tipos
  2. Referências
  3. Objetos
  4. Arrays
  5. Destructuring
  6. Strings
  7. Funções
  8. Arrow Functions (Lambdas)
  9. Construtores
  10. Módulos
  11. Iteradores e Geradores
  12. Propriedades
  13. Variáveis
  14. Hoisting
  15. Operadores
  16. Blocos
  17. Comentários
  18. Whitespace
  19. Vírgulas
  20. Ponto e vírgula
  21. Casting
  22. Nomes
  23. Acessores
  24. Events
  25. jQuery
  26. Anotações de Tipo
  27. Interfaces
  28. Organização
  29. Compatibilidade com ECMAScript 5
  30. ECMAScript 6
  31. Typescript 1.5
  32. License

Tipos

  • 1.1 Primitivo: A manipulação de um tipo primitivo é feita diretamente no seu valor.

    • string
    • number
    • boolean
    • null
    • undefined
    const foo = 1;
    let bar = foo;
    
    bar = 9;
    
    console.log(foo, bar); // => 1, 9
  • 1.2 Complexo: A manipulação de um tipo complexo é feito por uma referência para o seu valor.

    • object
    • array
    • function
    const foo = [1, 2];
    const bar = foo;
    
    bar[0] = 9;
    
    console.log(foo[0], bar[0]); // => 9, 9

⬆ voltar ao topo

Referências

  • 2.1 Use const para todas as suas referências; evite usar var.

Isso garante que você não vá reatribuir suas referências (mutação), o que pode levar a bugs e código de difícil compreensão. Com objeto complexos, o const não garante a imutabilidade dos valores dos atributos do objeto.

```javascript
// ruim
var a = 1;
var b = 2;

// bom
const a = 1;
const b = 2;
```
  • 2.2 Se as referências necessitam ser alteradas, use let ao invés var.

let possui escopo de bloco (block-scoped) ao invés do escopo de função (function-scoped) que var possui.

```javascript
// ruim
var count = 1;
if (true) {

  count += 1;

}

// bom, usando let
let count = 1;
if (true) {

  count += 1;

}
```
  • 2.3 let e const possuem escopo de block (block-scoped). No Typescript, o compilador faz a verificação e emite um erro em tempo de compilação.

    // const e let existem apenas nos blocos em que foram definidos
    {
      let a = 1;
      const b = 1;
    }
    console.log(a); // Erro do TSC
    console.log(b); // Erro do TSC

⬆ voltar ao topo

Objetos

  • 3.1 Utilize a sintaxe literal para criar um objeto

    // ruim
    const item = new Object();
    
    // bom
    const item = {};
  • 3.2 Não utilize palavras reservadas como nome de atributos. Garante a compatibilidade com versões antigas do IE.

    // ruim
    const superman = {
      default: { clark: 'kent' },
      private: true,
    };
    
    // bom
    const superman = {
      defaults: { clark: 'kent' },
      hidden: true,
    };
  • 3.3 Utilize sinônimos legíveis no lugar de palavras reservadas.

    // ruim
    const superman = {
      class: 'alien',
    };
    
    // ruim
    const superman = {
      klass: 'alien',
    };
    
    // bom
    const superman = {
      type: 'alien',
    };

  • 3.4 Utilize propriedades computadas quando criar objetos com nome dinâmico de propriedade.

Permite que você defina todas as propridades de um objeto em apenas um lugar.

```javascript

const getKey = function(k) {

  return `um atributo chamado ${k}`;

}

// ruim
const obj = {
  id: 5,
  name: 'San Francisco',
};
obj[getKey('enabled')] = true;

// bom
const obj = {
  id: 5,
  name: 'San Francisco',
  [getKey('enabled')]: true,
};
```

  • 3.5 Utilize lambdas (arrow functions) ou object-shorthand methods para objetos com métodos ao invés de propriedades ou funções anônimas.

    // ruim
    const atom = {
      value: 1,
      addValue: function (value) {
        return atom.value + value;
      },
    };
    
    // bom
    const atom = {
      value: 1,
      addValue(value) {
        return atom.value + value;
      },
    };
    
    // bom
    const atom = {
      value: 1,
      addValue: (value) => atom.value + value
    };

  • 3.6 Utilize a forma reduzida de atribuição de valor.

Maneira mais sucinta e descritiva.

```javascript
const lukeSkywalker = 'Luke Skywalker';

// ruim
const obj = {
  lukeSkywalker: lukeSkywalker,
};

// bom
const obj = {
  lukeSkywalker,
};
```
  • 3.7 Agrupe as atribuições de forma reduzida no começo da declaração do objeto.

Facilita o entendimento das propriedades atribuídas de forma reduzida.

```javascript
const anakinSkywalker = 'Anakin Skywalker';
const lukeSkywalker = 'Luke Skywalker';

// ruim
const obj = {
  episodeOne: 1,
  twoJedisWalkIntoACantina: 2,
  lukeSkywalker,
  episodeThree: 3,
  mayTheFourth: 4,
  anakinSkywalker,
};

// bom
const obj = {
  lukeSkywalker,
  anakinSkywalker,
  episodeOne: 1,
  twoJedisWalkIntoACantina: 2,
  episodeThree: 3,
  mayTheFourth: 4,
};
```

⬆ voltar ao topo

Arrays

  • 4.1 Utilize a sintaxe literal para criar arrays.

    // ruim
    const items = new Array();
    
    // bom
    const items = [];
  • 4.2 Utilize Array#push ao invés de atribuição direta para adicionar itens ao array.

    const someStack = [];
    
    
    // ruim
    someStack[someStack.length] = 'abracadabra';
    
    // bom
    someStack.push('abracadabra');

  • 4.3 Utilize array spreads ... para copiar arrays.

    // ruim
    const len = items.length;
    const itemsCopy = [];
    let i;
    
    for (i = 0; i < len; i++) {
      itemsCopy[i] = items[i];
    }
    
    // bom
    const itemsCopy = [...items];
  • 4.4 Para converter um objeto array-like para um array, utilize Array#from.

    const foo = document.querySelectorAll('.foo');
    const nodes = Array.from(foo);

⬆ voltar ao topo

Destructuring

  • 5.1 Utilize object destructuring quando é necessário acessar e utilizar múltiplas propriedades de um objeto.

Com destructuring é desnecessário criar referências temporárias para utilizar as propriedades do objeto.

```javascript
// ruim
const getFullName = function(user) {

  const firstName = user.firstName;
  const lastName = user.lastName;

  return `${firstName} ${lastName}`;

}

// bom
const getFullName = function(obj) {

  const { firstName, lastName } = obj;
  return `${firstName} ${lastName}`;

}

// muito bom
const getFullName = function({ firstName, lastName }) {

  return `${firstName} ${lastName}`;

}
```
  • 5.2 Utilize array destructuring.

    const arr = [1, 2, 3, 4];
    
    // ruim
    const first = arr[0];
    const second = arr[1];
    
    // bom
    const [first, second] = arr;
  • 5.3 Utilize object destructuring para múltiplos valores de retorno, não array destructuring.

Você pode adicionar novas propriedades sem quebrar as funções que utilizam o método.

```javascript
// ruim
const processInput = function(input) {
  return [left, right, top, bottom];

}

// o caller precisa pensar sobre a ordem dos valores dentro do array
const [left, __, top] = processInput(input);

// bom
const processInput = function(input) {
  return { left, right, top, bottom };

}

// o caller seleciona apenas os atributos necessários
const { left, right } = processInput(input);
```

⬆ voltar ao topo

Strings

  • 6.1 Aspas simples '' para strings.

    // ruim
    const name = "Capt. Janeway";
    
    // bom
    const name = 'Capt. Janeway';
  • 6.2 Strings mais longas que 120 caracteres devem ser escritas em mútiplas linhas.

  • 6.3 Nota: Concatenação de strings longas pode causar problemas de performance. jsPerf & Discussion.

    // ruim
    const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
    
    // ruim
    const errorMessage = 'This is a super long error that was thrown because \
    of Batman. When you stop to think about how Batman had anything to do \
    with this, you would get nowhere \
    fast.';
    
    // bom
    const errorMessage = 'This is a super long error that was thrown because ' +
      'of Batman. When you stop to think about how Batman had anything to do ' +
      'with this, you would get nowhere fast.';

  • 6.4 Quando construindo strings programaticamente, utilize templates.

Templates são mais legíveis, possuem sintaxe concisa e interpolação.

```javascript
// ruim
const sayHi = function(name) {

  return 'Olá ' + name + '.';

}

// ruim
const sayHi = function(name) {

  return ['Olá ', name, '.'].join();

}

// bom
const sayHi = function(name) {

  return `Olá ${name}.`;

}
```

⬆ voltar ao topo

Funções

  • 7.1 Declare funções ao invés de criar expressões

Declarações são nomeadas e são mais fáceis de identificar no call stack.

```javascript

// ruim
const foo = function() {
};

// ruim
const foo = () => {
};

// bom
function foo() {
}
```
  • 7.2 Expressões:

    // immediately-invoked function expression (IIFE)
    (() => {
      console.log('Welcome to the Internet. Please follow me.');
    })();
  • 7.3 Nunca declare a função em um bloco que não seja de função (if, while, etc). Ao invés, atribua a função a uma variável. Browsers interpretam diferentemente esse comportamento.

  • 7.4 Nota: ECMA-262 define um block como uma lista de comandos. Uma declaração de função não é um comando. Nota ECMA-262.

    // ruim
    if (currentUser) {
    
      const test = function() {
    
        console.log('Nope.');
    
      }
    
    }
    
    // bom
    let test;
    if (currentUser) {
    
      test = () => {
    
        console.log('Yup.');
    
      };
    
    }
  • 7.5 Nunca nomeie um parametro arguments. Isso terá precedência em cima do arguments que é dado para cada escopo de função.

    // ruim
    const nope = function(name, options, arguments) {
      // comandos
    }
    
    // bom
    const yup = function(name, options, args) {
      // comandos
    }

  • 7.6 Nunca utilize arguments, escolha a sintaxe rest ....

... é explicito quanto quais argumentos você deseja utilizar. Argumentos rest estão em um Array, e não em um array-like object como o arguments.

```javascript
// ruim
const concatenateAll = function() {

  const args = Array.prototype.slice.call(arguments);
  return args.join('');

}

// bom
const concatenateAll = function(...args) {

  return args.join('');

}
```

  • 7.7 Utilize a sintaxe de parâmetro default ao invés de alterar argumentos da função.

    // muito ruim
    const handleThings = function(opts) {
      // não devemos alterar argumentos de função.
      // se opts é falso será setado para um objeto que talvez introduza bugs
      opts = opts || {};
      // ...
    }
    
    // ruim
    const handleThings = function(opts) {
    
      if (opts === void 0) {
    
        opts = {};
    
      }
      // ...
    }
    
    // bom
    const handleThings = function(opts = {}) {
      // ...
    }
  • 7.8 Use parâmetros default com cuidado.

var b = 1;
const count = function(a = b++) {

  console.log(a);

}
count();  // 1
count();  // 2
count(3); // 3
count();  // 3
  • 7.9 Sempre coloque parâmetros default por último.
// ruim
function createObj(opts = {}, id){
  //...
}

// bom
function createObj(id, opts = {}){
  //...
}
  • 7.10 Nunca use o construtor Function para criar uma função.

Isso deixa o código vulnerável ( eval() );

// ruim
let add = new Function('a','b','return a + b');
  • 7.11 Atenção com o espaçamento.

Consistência é bom, e não se deve adicionar ou remover espaços quando adiciona-se ou altera-se um nome.

// ruim
const f = function(){};
const g = function (){};
const h = function() {};

// bom
const x = function () {};
const y = function a() {};

⬆ voltar ao topo

Arrow Functions

  • 8.1 Quando function expressions são necessárias, como por exemplo passando uma função anônima como parâmetro, utilize a sintaxe de arrow.

Se a função for razoávelmente complexa, talvez seja melhor mover essa lógica para uma declaração.

```javascript
// ruim
[1, 2, 3].map(function (x) {

  return x * x;

});

// bom
[1, 2, 3].map((x) => {

  return x * x;

});

// bom
[1, 2, 3].map((x) => x * x;);
```
  • 8.2 Se o corpo da função tiver o tamanho de uma linha e apenas um argumento, é dispensável o uso de parênteses e chaves, e pode ser utilizado o return implícito. Se não, utilize as chaves, parentes e return

Syntactic sugar. Muito legível.

Não utilize se a função retorna um objeto complexo.

```javascript
// bom
[1, 2, 3].map(x => x * x);

// bom
[1, 2, 3].reduce((total, n) => {
  return total + n;
}, 0);
```

- [8.3](#8.3) <a name='8.3'></a> Se a expressão se estender por várias linhas, envolva-a com parênteses para melhor legibilidade.

> Mostra claramente onde a expressão começa e termina.

```javascript
// ruim
[1, 2, 3].map(number => 'As time went by, the string containing the ' +
  `${number} became much longer. So we needed to break it over multiple ` +
  'lines.'
);

// bom
[1, 2, 3].map(number => (
  `As time went by, the string containing the ${number} became much ` +
  'longer. So we needed to break it over multiple lines.'
));
```

- [8.4](#8.4) <a = name='8.4"></a> Se a função recebe apenas um argumento, não utilize parênteses.

```javascript
// bom
[1, 2, 3].map(x => x * x);

// bom
[1, 2, 3].reduce((y, x) => x + y);
```

⬆ voltar ao topo

Construtores

  • 9.1 Sempre utilize class. Evite manipular o prototype diretamente.

class é mais concisa e é mais familiar para C# devs.

```javascript
// ruim
function Queue(contents = []) {

  this._queue = [...contents];

}
Queue.prototype.pop = function() {

  const value = this._queue[0];
  this._queue.splice(0, 1);
  return value;

}


// bom
class Queue {

  constructor(contents = []) {

    this._queue = [...contents];

  }

  pop() {

    const value = this._queue[0];
    this._queue.splice(0, 1);
    return value;

  }

}
```
  • 9.2 Utilize extends para herança.

É uma maneira simples de herdar a funcionalidade do prototype sem quebrar instanceof.

```javascript
// ruim
const inherits = require('inherits');
function PeekableQueue(contents) {

  Queue.apply(this, contents);

}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {

  return this._queue[0];

}

// bom
class PeekableQueue extends Queue {

  peek() {

    return this._queue[0];

  }

}
```
  • 9.3 Métodos podem retornar this para implementar method chaining.

    // ruim
    Jedi.prototype.jump = function() {
    
      this.jumping = true;
      return true;
    
    };
    
    Jedi.prototype.setHeight = function(height) {
    
      this.height = height;
    
    };
    
    const luke = new Jedi();
    luke.jump(); // => true
    luke.setHeight(20); // => undefined
    
    // bom
    class Jedi {
    
      jump() {
    
        this.jumping = true;
        return this;
    
      }
    
      setHeight(height) {
    
        this.height = height;
        return this;
    
      }
    
    }
    
    const luke = new Jedi();
    
    luke.jump()
      .setHeight(20);
  • 9.4 É aconselhado reescrever o método toString() se necessário

    class Jedi {
    
      contructor(options = {}) {
    
        this.name = options.name || 'no name';
    
      }
    
      getName() {
    
        return this.name;
    
      }
    
      toString() {
    
        return `Jedi - ${this.getName()}`;
    
      }
    
    }

⬆ voltar ao topo

Módulos

  • 10.1 Utilize (import/export) como padrão.

    // ruim
    const AirbnbStyleGuide = require('./AirbnbStyleGuide');
    module.exports = AirbnbStyleGuide.es6;
    
    // bom
    import AirbnbStyleGuide from './AirbnbStyleGuide';
    export default AirbnbStyleGuide.es6;
    
    // muito bom - angularjs2 syntax
    import { es6 } from './AirbnbStyleGuide';
    export default es6;
  • 10.2 Não export diretamente de um import.

Ter uma maneira de importar módulos e uma maneira para exportar deixa o código mais consistente.

```javascript
// ruim
// filename es6.js
export { es6 as default } from './airbnbStyleGuide';

// bom
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
```
  • 10.3 Não utilize wildcards

    // ruim
    import * as PromobERPCommon from './common';
    
    //bom
    import PromobERPCommon from './common;'

⬆ voltar ao topo

Iteradores e Geradores

  • 11.1 Evite iteradores. Prefira utilizar funções como map(), reduce(), forEach() ao invés de for-of.

Isso fortalece a regra de referências imutáveis.

```javascript
const numbers = [1, 2, 3, 4, 5];

// ruim
let sum = 0;
for (let num of numbers) {

  sum += num;

}

sum === 15;

// bom
let sum = 0;
numbers.forEach((num) => sum += num);
sum === 15;

// muito bom
const sum = numbers.reduce((total, num) => total + num, 0);
sum === 15;
```
  • 11.2 Não utilize geradores por enquanto.

⬆ voltar ao topo

Propriedades

  • 12.1 Use notação de ponto para acessar propriedades.

    const luke = {
      jedi: true,
      age: 28,
    };
    
    // ruim
    const isJedi = luke['jedi'];
    
    // bom
    const isJedi = luke.jedi;
  • 12.2 Utilize a sintaxe de indexação [] em casos raros. Prefira criar uma interface e utilizar a notação de ponto quando possível.

    const luke = {
      jedi: true,
      age: 28,
    };
    
    const getProp = function(prop) {
    
      return luke[prop];
    
    }
    
    const isJedi = getProp('jedi');

⬆ voltar ao topo

Variáveis

  • 13.1 Sempre utilize const/let para declarar variáveis, dependendendo da necessidade. Prefira const.

    // ruim
    superPower = new SuperPower();
    
    // bom
    const superPower = new SuperPower();
  • 13.2 Utilize uma declaração const/let por variável.

    É mais fácil de ler e adicionar variáveis.

    // ruim
    const items = getItems(),
        goSportsTeam = true,
        dragonball = 'z';
    
    // ruim
    // (encontre o erro :) )
    const items = getItems(),
        goSportsTeam = true;
        dragonball = 'z';
    
    // bom
    const items = getItems();
    const goSportsTeam = true;
    const dragonball = 'z';
  • 13.3 Agrupe todos seus consts e todos seus lets.

Ajuda a organizar o código.

```javascript
// ruim
let i, len, dragonball,
    items = getItems(),
    goSportsTeam = true;

// ruim
let i;
const items = getItems();
let dragonball;
const goSportsTeam = true;
let len;

// bom
const goSportsTeam = true;
const items = getItems();
let dragonball;
let i;
let length;
```
  • 13.4 Atribua os valores quando necessário, mas declare as variáveis em lugares sensatos.

Lembre-se: let e const possuem escopo de bloco (block-scoped) e não escopo de função (function-scoped).

```javascript
// bom
function() {

  test();
  console.log('doing stuff..');

  //..other stuff..

  const name = getName();

  if (name === 'test') {

    return false;

  }

  return name;

}

// ruim - chamada de função desnecessária
function(hasName) {

  const name = getName();

  if (!hasName) {

    return false;

  }

  this.setFirstName(name);

  return true;

}

// bom
function(hasName) {

  if (!hasName) {

    return false;

  }

  const name = getName();
  this.setFirstName(name);

  return true;

}
```

⬆ voltar ao topo

Hoisting

  • 14.1 Hoisting é o comportamento padrão do javascript de mover declarações para o topo. Declarações var sofrem com isso, mas a atribuição de um valor para uma variável var não sofre. Declarações const e let possuem um conceito chamado Temporal Dead Zones (TDZ). É importante saber que typeof não é seguro.

    // isso não funcionaria se notDefined não tivesse sido declarada
    function example() {
    
      console.log(notDefined); // => compilador não encontra a variável
    
    }
    
    // isso funcionaria devido ao hoisting, mas o valor da váriavel não estaria setado
    function example() {
    
      console.log(declaredButNotAssigned); // => undefined
      var declaredButNotAssigned = true;
    
    }
    
    // o interpretador está aplicando o hoisting na variável, o exemplo acima poderia ser reescrito dessa maneira:
    function example() {
    
      let declaredButNotAssigned;
      console.log(declaredButNotAssigned); // => undefined
      declaredButNotAssigned = true;
    
    }
    
    // utilizando const e let
    function example() {
    
      console.log(declaredButNotAssigned); // => Erro do TSC
      console.log(typeof declaredButNotAssigned); // => Erro do TSC
      const declaredButNotAssigned = true;
    
    }
  • 14.2 Funções anônimas sofrem "hoist" da própria variável, mas não a atribuição do corpo da função.

    function example() {
    
      console.log(anonymous); // => undefined
    
      anonymous(); // => TypeError anonymous is not a function
    
      var anonymous = function() {
    
        console.log('anonymous function expression');
    
      };
    
    }
  • 14.3 Funções nomeadas que são atribuídas a variáveis sofrem "hoist" do nome da variável, mas não do nome da função nem da implementação da função.

    function example() {
    
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      superPower(); // => ReferenceError superPower is not defined
    
      var named = function superPower() {
    
        console.log('Flying');
    
      };
    
    }
    
    // o mesmo vale se o nome da função é igual ao nome da variável
    function example() {
    
      console.log(named); // => undefined
    
      named(); // => TypeError named is not a function
    
      var named = function named() {
    
        console.log('named');
    
      }
    
    }
  • 14.4 Declarações de funções sofrem "hoist" no nome da função e na sua implementação.

    function example() {
    
      superPower(); // => Flying
    
      function superPower() {
    
        console.log('Flying');
    
      }
    
    }
  • Mais Informações: JavaScript Scoping & Hoisting by Ben Cherry.

⬆ voltar ao topo

Operadores

  • 15.1 SEMPRE utilize === e !== ao invés de == e !=.

  • 15.2 Comandos condicionais como o if avaliam a expressão utilizando coercion com o método abstrato ToBoolean e seguem as seguintes regras:

    • Objects são true
    • Undefined é false
    • Null é false
    • Booleans recebem o valor do booleano
    • Numbers são false se +0, -0, ou NaN, senão são true
    • Strings são false se é uma string vazia '', senão são true
    if ([0]) {
      // true
      // Array é um objeto, objeto é true
    }
  • 15.3 Utilize atalhos.

    // ruim
    if (name !== '') {
      // ...stuff...
    }
    
    // bom
    if (name) {
      // ...stuff...
    }
    
    // ruim
    if (collection.length > 0) {
      // ...stuff...
    }
    
    // bom
    if (collection.length) {
      // ...stuff...
    }
  • 15.4 Para mais informações: Truth Equality and JavaScript by Angus Croll.

⬆ voltar ao topo

Blocos

  • 16.1 Utilize chaves para blocos multi-linhas. Pode-se omitir as chaves em blocos de uma linha.

    // ruim
    if (test) return false;
    
    // bom
    if (test)
      return false;
    
    // muito bom
    if (test) {
      return false;
    }
    
    // ruim
    function() { return false; }
    
    // bom
    function() {
      return false;
    }
  • 16.2 Se você está utilizando blocos multi-linhas com if e else, coloque else na mesma linha do fechamento do bloco do if.

    // ruim
    if (test) {
      thing1();
      thing2();
    }
    else {
      thing3();
    }
    
    // bom
    if (test) {
      thing1();
      thing2();
    } else {
      thing3();
    }
    • 16.3 Não omita as chaves em blocos multi-linha.

    Omitir as chaves nesse caso facilita bugs.

    // ruim
    if (test)
      thing1();
      thing2();
    else
      thing3();
    
    // bom
    if (test) {
      thing1();
      thing2();
    } else {
      thing3();
    }

⬆ voltar ao topo

Comentários

  • 17.1 Utilize /** ... */ para comentários multi-linha. Inclua uma descrição descrição e tente não ser redundante. Se o código está claro o suficiente para outra pessoa, reavalie se comentários são realmente necessários.

    // ruim
    // make() retorna um novo elemento
    // baseado na tag
    //
    const make = function(tag) {
    
      // ...stuff...
    
      return element;
    
    }
    
    // bom
    /**
     * make() retorna um novo elemento
     * baseado na tag
     */
    const make = function(tag) {
    
      // ...stuff...
    
      return element;
    
    }
  • 17.2 Utilize // para comentários de uma linha. Comente na linha imediatamente acima a linha do código, e deixe uma linha branco entre o comando anterior e o comentário.

    // ruim
    const active = true;  // is current tab
    
    // bom
    // is current tab
    const active = true;
    
    // ruim
    const getType = function() {
    
      console.log('fetching type...');
      // set the default type to 'no type'
      const type = this._type || 'no type';
    
      return type;
    
    }
    
    // bom
    const getType = function() {
    
      console.log('fetching type...');
    
      // set the default type to 'no type'
      const type = this._type || 'no type';
    
      return type;
    
    }
  • 17.3 Utilize prefixos FIXME ou TODO quando necessário.

  • 17.4 Utilize //FIXME: para descrever problemas.

    class Calculator {
    
      constructor() {
        // FIXME: não utilizar variável global 
        total = 0;
      }
    
    }
  • 17.5 Utilize //TODO: para descrever soluções.

    class Calculator {
    
      constructor() {
        // TODO: total deveria ser inserido via parâmetro
        this.total = 0;
      }
    
    }

⬆ voltar ao topo

Whitespace

  • 18.1 Utilize tabs como 4 espaços - padrão VS.

    // ruim
    function() {
    
    ∙∙const name;
    
    }
    
    // ruim
    function() {
    
    ∙const name;
    
    }
    
    // bom
    function() {
    
    ∙∙∙∙const name;
    
    }
  • 18.2 Coloque um espaço antes da chave inicial.

    // ruim
    const test = function(){
    
      console.log('test');
    
    }
    
    // bom
    const test = function() {
    
      console.log('test');
    
    }
    
    // ruim
    dog.set('attr',{
      age: '1 year',
      breed: 'Bernese Mountain Dog',
    });
    
    // bom
    dog.set('attr', {
      age: '1 year',
      breed: 'Bernese Mountain Dog',
    });
  • 18.3 Coloque um espaço antes de abrir parênteses em comandos de controle (if, while etc.). Não coloque espaços antes da lista de argumentos de uma função.

    // ruim
    if(isJedi) {
    
      fight ();
    
    }
    
    // bom
    if (isJedi) {
    
      fight();
    
    }
    
    // ruim
    const fight = function () {
    
      console.log ('Swooosh!');
    
    }
    
    // bom
    const fight = function() {
    
      console.log('Swooosh!');
    
    }
  • 18.4 Utilize espaço para separar operadores.

    // ruim
    const x=y+5;
    
    // bom
    const x = y + 5;
  • 18.5 Acabe arquivos com um caracter de nova linha.

    // bad
    (function(global) {
      // ...stuff...
    })(this);
    // bad
    (function(global) {
      // ...stuff...
    })(this);
    
    // good
    (function(global) {
      // ...stuff...
    })(this);
  • 18.5 Idente quando estiver fazendo method chaining de vários métodos. Utilize o ponto no começo da linha para demonstrar que é um método e não um comando novo.

    // ruim
    $('#items').find('.selected').highlight().end().find('.open').updateCount();
    
    // ruim
    $('#items').
      find('.selected').
      highlight().
      end().
      find('.open').
      updateCount();
    
    // bom
    $('#items')
      .find('.selected')
      .highlight()
      .end()
      .find('.open')
      .updateCount();
    
    // ruim
    const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true)
        .attr('width', (radius + margin) * 2).append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);
    
    // bom
    const leds = stage.selectAll('.led')
        .data(data)
        .enter().append('svg:svg')
        .classed('led', true)
        .attr('width', (radius + margin) * 2)
        .append('svg:g')
        .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')')
        .call(tron.led);
  • 18.6 Insira uma linha em branco após abrir o bloco e antes de fechar ele.

// ruim
if (foo) {
  return bar;
}

// bom
if (foo) {

  return bar;

}

// ruim
const baz = function(foo) {
  return bar;
}

// bom
const baz = function(foo) {

  return bar;

}
  • 18.7 Insira uma linha em branco após o final do bloco

    // ruim
    if (foo) {
    
      return bar;
    
    }
    return baz;
    
    // bom
    if (foo) {
    
      return bar;
    
    }
    
    return baz;
    
    // ruim
    const obj = {
      foo() {
      },
      bar() {
      },
    };
    return obj;
    
    // bom
    const obj = {
      foo() {
      },
    
      bar() {
      },
    };
    
    return obj;

⬆ voltar ao topo

Vírgulas

  • 19.1 Vírgulas no ínicio: Nope.

    // ruim
    const story = [
        once
      , upon
      , aTime
    ];
    
    // bom
    const story = [
      once,
      upon,
      aTime,
    ];
    
    // ruim
    const hero = {
        firstName: 'Ada'
      , lastName: 'Lovelace'
      , birthYear: 1815
      , superPower: 'computers'
    };
    
    // bom
    const hero = {
      firstName: 'Ada',
      lastName: 'Lovelace',
      birthYear: 1815,
      superPower: 'computers',
    };
  • 19.2 DISCUSS - Vírgula sobrando: Nope.

Typescript não elimina a vírgula que sobra.

```javascript
// ruim
const hero = {
  firstName: 'Dana',
  lastName: 'Scully',
};

const heroes = [
  'Batman',
  'Superman',
];

// bom
const hero = {
  firstName: 'Dana',
  lastName: 'Scully'
};

const heroes = [
  'Batman',
  'Superman'
];

```

⬆ voltar ao topo

Ponto e vírgula

  • 20.1 Sempre.

    // ruim
    (function() {
    
      const name = 'Skywalker'
      return name
    
    })()
    
    // bom
    (() => {
    
      const name = 'Skywalker';
      return name;
    
    })();
    
    // bom - closures não se tornam argumentos no caso de concatenação
    ;(() => {
    
      const name = 'Skywalker';
      return name;
    
    })();

    Read more.

⬆ voltar ao topo

Casting

  • 21.1 Faça o cast no início do comando.

  • 21.2 Strings:

    //  => this.reviewScore = 9;
    
    // ruim
    const totalScore = this.reviewScore + '';
    
    // bom
    const totalScore = String(this.reviewScore);
  • 21.3 Utilize parseInt para Numbers e sempre utilize um radix para casting.

    const inputValue = '4';
    
    // ruim
    const val = new Number(inputValue);
    
    // ruim
    const val = +inputValue;
    
    // ruim
    const val = inputValue >> 0;
    
    // ruim
    const val = parseInt(inputValue);
    
    // bom
    const val = Number(inputValue);
    
    // bom
    const val = parseInt(inputValue, 10);
  • 21.4 parseInt pode virar um bottleneck. Utilize Bitshift caso tenha se tornado um bottleneck por razões de performance, comente porque e o que você está fazendo.

    // good
    /**
     * parseInt estava deixando o código lento
     * Bitshifting a string para transformar-lá num Number deixou muito mais rápido
     */
    const val = inputValue >> 0;
  • 21.5 Note: Cuidado ao utilizar bitshift. Numeros são representados por 64 bits, porém operações bitshifts sempre retornam 32 bits. O Maior inteiro de 32 bits é 2.147.483.647.

    2147483647 >> 0 //=> 2147483647
    2147483648 >> 0 //=> -2147483648
    2147483649 >> 0 //=> -2147483647
  • 21.6 Booleans:

    const age = 0;
    
    // ruim
    const hasAge = new Boolean(age);
    
    // bom
    const hasAge = Boolean(age);
    
    // bom
    const hasAge = !!age;

⬆ voltar ao topo

Nomes

  • 22.1 Seja sempre descritivo com o nome das suas funções.

    // ruim
    function q() {
      // ...stuff...
    }
    
    // bom
    function query() {
      // ..stuff..
    }
    
    
    // muito bom
    function queryStuffOnDataBase() {
      // ..stuff..
    }
  • 22.2 Utilize camelCase para nomear objetos, métodos, funções, campos privados e instâncias.

    // ruim
    const OBJEcttsssss = {};
    const this_is_my_object = {};
    const c = function() {}
    
    // bom
    const thisIsMyObject = {};
    const thisIsMyFunction = function() {}
  • 22.3 Utilize PascalCase para nomear classes, campos públicos, modulos ou interfaces - essas sempre começando por I.

    // ruim
    function user(options) {
    
      this.name = options.name;
    
    }
    
    const bad = new user({
      name: 'nope',
    });
    
    // bom
    module AperatureScience {
    
      class User {
    
        constructor(options) {
    
          this.name = options.name;
    
        }
    
      }
    
    }
    
    const good = new AperatureScience.User({
      name: 'yup',
    });

⬆ voltar ao topo

Acessores

  • 23.1 DISCUSS Utilize a sintaxe de get() e set() do Typescript

    class Foo{
       private bar : number;
       
       get Bar() : number {
         return this.bar;
       }
       
       set Bar(value : number) {
         this.bar = value;
       }
    }

⬆ voltar ao topo

Events

  • 24.1 Placeholder de AngularJS events

⬆ voltar ao topo

jQuery

  • 25.1 Utilize o prefixo $.

    // ruim
    const sidebar = $('.sidebar');
    
    // bom
    const $sidebar = $('.sidebar');
  • 25.2 Faça cache de buscas do jQuery.

    // ruim
    function setSidebar() {
    
      $('.sidebar').hide();
    
      // ...stuff...
    
      $('.sidebar').css({
        'background-color': 'pink'
      });
    
    }
    
    // bom
    function setSidebar() {
    
      const $sidebar = $('.sidebar');
      $sidebar.hide();
    
      // ...stuff...
    
      $sidebar.css({
        'background-color': 'pink'
      });
    
    }
  • 25.3 Para queries no DOM utilize cascading $('.sidebar ul') ou parent > child $('.sidebar > ul'). jsPerf

  • 25.4 Utilize find com queries jQuery DISCUSS

    // ruim
    $('ul', '.sidebar').hide();
    
    // ruim
    $('.sidebar').find('ul').hide();
    
    // bom
    $('.sidebar ul').hide();
    
    // bom
    $('.sidebar > ul').hide();
    
    // bom
    $sidebar.find('ul').hide();

⬆ voltar ao topo

Anotações de Tipo

  • 26.1 Placeholder de anotações de tipos.

  • 26.2 Utilize T para o tipo da variável.
function identify<T>(arg: T): T {

    return arg;
    
}
  • 26.3 Se mais de um tipo é necessário, começe por Te siga em ordem alfabética.
function find<T, U extends Findable>(needle: T, haystack: U): U {

  return haystack.find(needle)

}
  • 26.4 Quando possível, utilize a inferência de tipos do Typescript.
// ruim
const output = identify<string>("myString");

// bom
const output = identity("myString");
  • 26.5 Quando criar factories utilizando generics, não esqueça do construtor.
function create<t>(thing: {new(): T;}): T {

  return new thing();

}

⬆ voltar ao topo

Interfaces

  • 27.1 Nomeie a interface sempre iniciando pela letra I.

⬆ voltar ao topo

Organização

⬆ voltar ao topo

Compatibilidade com ECMAScript 5

⬆ voltar ao topo

ECMAScript 6

  • 30.1 ES6 Style Features
  1. Arrow Functions
  2. Classes
  3. Object Shorthand
  4. Object Concise
  5. Object Computed Properties
  6. Template Strings
  7. Destructuring
  8. Default Parameters
  9. Rest
  10. Array Spreads
  11. Let and Const
  12. Iterators and Generators
  13. Modules

⬆ voltar ao topo

Typescript 1.5

  • 31.1 ES6 Typescript Features
  1. Type Annotations
  2. Interfaces
  3. Classes
  4. Modules
  5. Generics

⬆ voltar ao topo

License

(The MIT License)

Copyright (c) 2014 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

⬆ voltar ao topo

typescript's People

Contributors

hshoff avatar goatslacker avatar ssorallen avatar ajacksified avatar justjake avatar mitsuruog avatar spikebrehm avatar tgcandido avatar robloach avatar herringtondarkholme avatar wyattdanger avatar vahan-hartooni avatar nicoder avatar timofurrer avatar climbsrocks avatar iamnirav avatar reissbaker avatar koenpunt avatar nmussy avatar unkillbob avatar thesavior avatar carterchung avatar deanxu avatar triang3l avatar tipjs avatar endangeredmassa avatar ryun avatar rkushnir avatar robertd avatar qorbani avatar

Watchers

James Cloos avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.