|
| 1 | +--- |
| 2 | +title: Do's and Don'ts |
| 3 | +layout: docs |
| 4 | +permalink: /pt/docs/handbook/declaration-files/do-s-and-don-ts.html |
| 5 | +oneline: "Recomendações para escrita de arquivos d.ts" |
| 6 | +--- |
| 7 | + |
| 8 | +## Tipos Gerais |
| 9 | + |
| 10 | +## `Number`, `String`, `Boolean`, `Symbol` and `Object` |
| 11 | + |
| 12 | +_Nunca_ use os tipos `Number`, `String`, `Boolean`, `Symbol`, ou `Object` |
| 13 | +Esse tipos fazem referências a objetos não-primitivos que quase nunca são usados apropriadamente em códigos JavaScript. |
| 14 | + |
| 15 | +```ts |
| 16 | +/* Errado */ |
| 17 | +function reverte(s: String): String; |
| 18 | +``` |
| 19 | + |
| 20 | +_Sempre_ use os tipos `number`, `string`, `boolean`, e `symbol`. |
| 21 | + |
| 22 | +```ts |
| 23 | +/* OK */ |
| 24 | +function reverte(s: string): string; |
| 25 | +``` |
| 26 | + |
| 27 | +Ao invés de `Object`, use o tipo não-primitivo `object` ([adicionado em TypeScript 2.2](../release-notes/typescript-2-2.html#object-type)). |
| 28 | + |
| 29 | +## Generics |
| 30 | + |
| 31 | +_Nunca_ tenha um tipo genérico que não use os tipos de seus parâmetros. |
| 32 | +Veja mais detalhes em [TypeScript FAQ page](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-type-inference-work-on-this-interface-interface-foot--). |
| 33 | + |
| 34 | +## any |
| 35 | + |
| 36 | +_Nunca_ use `any` como tipo a não ser que você esteja no processo de migração do projeto de JavaScript para Typescript. O compilador _efetivamente_ trata `any` como "por favor desligue a verificação de tipo para essa coisa". Isso é similar a botar um comentário `@ts-ignore` em volta de cada uso da variável. Isso pode ser muito útil quando você está migrando pela primeira vez um projeto JavaScript para TypeScript pois pode definir o tipo para coisas que você ainda não migrou como `any`, mas em um projeto TypeScript completo você estará desabilitando a verificação de tipos para qualquer parte do seu programa que o use. |
| 37 | + |
| 38 | +Em casos onde você não sabe o tipo você quer aceitar, ou quando quer aceitar qualquer coisa pois irá passar adiante cegamente sem interagir, você pode usar [`unknown`](/play/#example/unknown-and-never). |
| 39 | + |
| 40 | + |
| 41 | +<!-- TODO: More --> |
| 42 | + |
| 43 | +## Tipos de Callback |
| 44 | + |
| 45 | +## Tipos de Retorno e Callbacks |
| 46 | + |
| 47 | +<!-- TODO: Reword; these examples make no sense in the context of a declaration file --> |
| 48 | + |
| 49 | +_Nunca_ use o tipo de retorno `any` para callbacks cujo o valor será ignorado: |
| 50 | + |
| 51 | +```ts |
| 52 | +/* ERRADO */ |
| 53 | +function fn(x: () => any) { |
| 54 | + x(); |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +_Sempre_ use o tipo de retorno `void` para callbacks cujo o valor será ignorado: |
| 59 | + |
| 60 | +```ts |
| 61 | +/* OK */ |
| 62 | +function fn(x: () => void) { |
| 63 | + x(); |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +_Por quê?_: Usar void é mais seguro porque te previne de acidentalmente usar o valor de retorno de `x` de forma não verificada: |
| 68 | + |
| 69 | +```ts |
| 70 | +function fn(x: () => void) { |
| 71 | + var k = x(); // oops! deveria fazer outra coisa |
| 72 | + k.facaAlgo(); // erro, mas ficaria OK se o tipo retorno tivesse sido 'any' |
| 73 | +} |
| 74 | +``` |
| 75 | + |
| 76 | +## Parâmetros Opcionais em Callbacks |
| 77 | + |
| 78 | +_Nunca_ use parâmetros opcionais em callbacks a não ser que você realmente tenha essa intenção: |
| 79 | + |
| 80 | +```ts |
| 81 | +/* ERRADO */ |
| 82 | +interface Buscador { |
| 83 | + retornaObjeto(pronto: (data: any, tempoDecorrido?: number) => void): void; |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +Isso tem um significado muito especifico: o callback `pronto` pode ser invocado com 1 argumento ou pode ser invocado com 2 argumentos. |
| 88 | +O autor provavelmente teve a intenção de dizer que o callback talvez não se importe com o parâmetro `tempoDecorrido`, mas não tem necessidade de fazer o parâmetro opcional para atingir isso -- |
| 89 | +sempre é valido prover um callback que aceita um numero menor de argumentos. |
| 90 | + |
| 91 | +_Sempre_ escreva parâmetros de callback como não-opcional: |
| 92 | + |
| 93 | +```ts |
| 94 | +/* OK */ |
| 95 | +interface Buscador { |
| 96 | + retornaObjeto(pronto: (data: any, tempoDecorrido: number) => void): void; |
| 97 | +} |
| 98 | +``` |
| 99 | + |
| 100 | +## Sobrecargas e Callbacks |
| 101 | + |
| 102 | +_Nunca_ escreva sobrecargas separadas que diferem apenas na aridade do callback: |
| 103 | + |
| 104 | +```ts |
| 105 | +/* ERRADO */ |
| 106 | +declare function antesDeTodos(acao: () => void, timeout?: number): void; |
| 107 | +declare function antesDeTodos( |
| 108 | + acao: (done: DoneFn) => void, |
| 109 | + timeout?: number |
| 110 | +): void; |
| 111 | +``` |
| 112 | + |
| 113 | +_Sempre_ escreva uma única sobrecarga usando a aridade maxima: |
| 114 | + |
| 115 | +```ts |
| 116 | +/* OK */ |
| 117 | +declare function antesDeTodos( |
| 118 | + acao: (done: DoneFn) => void, |
| 119 | + timeout?: number |
| 120 | +): void; |
| 121 | +``` |
| 122 | + |
| 123 | +_Por quê?_: Sempre é válido para um callback desprezar um parâmetro, então não tem necessidade de encurtar a sobrecarga. |
| 124 | +Provendo um callback mais curto primeiro permite funções incorretamente tipadas serem passadas adiante porque possuem correspondência com a primeira sobrecarga. |
| 125 | + |
| 126 | +## Sobrecargas de Funções |
| 127 | + |
| 128 | +## Ordenação |
| 129 | + |
| 130 | +_Nunca_ ponha sobrecargas genérias antes das mais específicas: |
| 131 | + |
| 132 | +```ts |
| 133 | +/* ERRADO */ |
| 134 | +declare function fn(x: any): any; |
| 135 | +declare function fn(x: HTMLElement): number; |
| 136 | +declare function fn(x: HTMLDivElement): string; |
| 137 | + |
| 138 | +var meuElem: HTMLDivElement; |
| 139 | +var x = fn(meuElem); // x: any, quê? |
| 140 | +``` |
| 141 | + |
| 142 | +_Sempre_ ordene sobrecargas pondo as assinaturas mais genéricas após as mais específicas: |
| 143 | + |
| 144 | +```ts |
| 145 | +/* OK */ |
| 146 | +declare function fn(x: HTMLDivElement): string; |
| 147 | +declare function fn(x: HTMLElement): number; |
| 148 | +declare function fn(x: any): any; |
| 149 | + |
| 150 | +var meuElem: HTMLDivElement; |
| 151 | +var x = fn(meuElem); // x: string, :) |
| 152 | +``` |
| 153 | + |
| 154 | +_Por quê?_: TypeScript escolhe a _primeira sobrecarga com correspondência_ ao resolver chamadas as funções. |
| 155 | +Quando uma sobrecarga mais recente "é mais geral" do que uma mais antiga, a mais antiga é efetivamente omitida e não pode ser chamada. |
| 156 | + |
| 157 | +## Use Parâmetros Opcionais |
| 158 | + |
| 159 | +_Nunca_ escreva muitas sobrecargas que diferem apenas em nos parâmetros finais: |
| 160 | + |
| 161 | +```ts |
| 162 | +/* ERRADO */ |
| 163 | +interface Exemplo { |
| 164 | + diff(um: string): number; |
| 165 | + diff(um: string, dois: string): number; |
| 166 | + diff(um: string, dois: string, tres: boolean): number; |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +_Sempre_ que possível use parâmetros opcionais: |
| 171 | + |
| 172 | +```ts |
| 173 | +/* OK */ |
| 174 | +interface Exemplo { |
| 175 | + diff(um: string, dois?: string, tres?: boolean): number; |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +Note que esse colapso deve ocorrer apenas quando todas as sobrecargas tiverem o mesmo tipo de retorno. |
| 180 | + |
| 181 | + |
| 182 | +_Por quê?_: Isso é importante por dois motivos. |
| 183 | + |
| 184 | +TypeScript resolve compatibilidade de assinaturas verificando se alguma assinatura do alvo pode ser chamada com os argumentos da fonte,_e argumentos estranhos são permitidos_. |
| 185 | +Esse código, por exemplo, expõe um bug apenas quando a assinatura é escrita corretamente usando parâmetros opcionais: |
| 186 | + |
| 187 | +```ts |
| 188 | +function fn(x: (a: string, b: number, c: number) => void) {} |
| 189 | +var x: Exemplo; |
| 190 | +// Quando escrito com sobrecarga, OK -- usado a primeira sobrecarga |
| 191 | +// Quando escrito com opcionais, devidamente um erro |
| 192 | +fn(x.diff); |
| 193 | +``` |
| 194 | + |
| 195 | +A segunda razão é quando um consumidor usa a funcionalidade "checagem estrita de nulos" do TypeScript. |
| 196 | +Porque parâmetros não especificados aparecem como `undefined` em javascript, geralmente é bom passar um `undefined` explícito para uma função com argumentos opcionais. |
| 197 | +Esse código, por exemplo, deveria ser OK sob nulos estritos: |
| 198 | + |
| 199 | +```ts |
| 200 | +var x: Exemplo; |
| 201 | +// Quando escrito com sobrecargas, um erro porque passa 'undefined' para 'string' |
| 202 | +// Quando escrito com opcionais, devidamente OK |
| 203 | +x.diff("algo", true ? undefined : "hora"); |
| 204 | +``` |
| 205 | + |
| 206 | +## Use Tipos de União |
| 207 | + |
| 208 | +_Nunca_ escreva sobrecargas que diferem por tipo em apenas um argumento: |
| 209 | + |
| 210 | +```ts |
| 211 | +/* ERRADO */ |
| 212 | +interface Momento { |
| 213 | + utcOffset(): number; |
| 214 | + utcOffset(b: number): Momento; |
| 215 | + utcOffset(b: string): Momento; |
| 216 | +} |
| 217 | +``` |
| 218 | + |
| 219 | +_Sempre_ que possível use tipos de união: |
| 220 | + |
| 221 | +```ts |
| 222 | +/* OK */ |
| 223 | +interface Momento { |
| 224 | + utcOffset(): number; |
| 225 | + utcOffset(b: number | string): Momento; |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +Perceba que nós não fizemos `b` opcional aqui porque os tipos de retorno das assinaturas são diferentes. |
| 230 | +_Por quê?_: Isso é importante para pessoas que estão "passando adiante" um valor para sua função: |
| 231 | + |
| 232 | +```ts |
| 233 | +function fn(x: string): void; |
| 234 | +function fn(x: number): void; |
| 235 | +function fn(x: number | string) { |
| 236 | + // Quando escrito com sobrecargas separadas, indevidamente um erro |
| 237 | + // Quando escrito com tipos de união, |
| 238 | + // When written with union types, devidamente OK |
| 239 | + return momento().utcOffset(x); |
| 240 | +} |
| 241 | +``` |
0 commit comments