DISCLAIMER: Não é intenção deste guia ser genérico. Mas sim ser rápido e direto.
EDIT: Atualizado para TS 2.0 não ser mais beta.
- Visual Studio Code (!= Visual Studio). Como eu disse, o guia não é pra ser genérico. Isso não quer dizer que você não possa fazer o mesmo com sublime ou atom ou vim, mas aqui estamos nos limitando ao VS Code pra sermos mais rápidos. Por motivos óbvios o VS Code possivelmente trás o melhor suporte de edição ao typescript (o qual é um dos principais motivos de usarmos o typescript).
Iniciando...
-
Instale o ts globalmente na sua máquina
npm i typescript -g
. Certifique-se que possui a versão 2 ou posterior (tsc -v
) -
Inicie o projeto node
npm init
-
Crie a pasta do projeto, a abra com o vscode e crie o
tsconfig.json
na raiz do projeto. Este arquivo também pode ser gerado pelo comandotsc --init
{
"compilerOptions" : {
"target" : "es6" ,
"module" : "commonjs" ,
"outDir" : "built" ,
"sourcemap" : true ,
"strictNullChecks" : true
} ,
"include" : [
"./src/**/*.ts" ,
"./src/**/*.js"
]
}
Aqui estamos sugerindo uma configuração de pastas separadas. Para cada arquivo .ts presente em ./src será criado um .js e um .map na pasta ./built.
-
CTRL + SHIFT + B
(ouF1
e digitar "build") > Configure Task Runner > Typescript - Watch Mode. Salve o arquivo criado. -
CTRL + SHIFT + B
novamente. (equivalente a chamartsc -w
). Faça isso sempre que abrir o projeto. Ao salvar as fontes, será efetuada a compilação. -
Escreva suas fontes .ts na pasta
src
. Vai compilar pra bastabuilt
.
Antes de tudo, configurar o debug do VS code com os mapas de fonte. Pra vc poder brincar.
- Aba debug, na lateral
- Clicar na engrenagem
- No arquivo
launch.json
, configuração "Launch", apontarprogram
para o ponto de partida .ts (não o js gerado) sourceMaps = true
outDir = "${worskpaceRoot}/built"
- Push play. Use os breakpoints nos arquivos .ts, não nos .js
O debugger é um dos grandes motivos de eu estar focando no VS code.
Pra abrir um terminal no VS Code: F1 + "terminal" ou CTRL + SHIFT + `
-
npm i @types/node -D
ao iniciar o projeto, para instalar as tipagens do node. -
Sempre que você fizer
npm i <algo> --save
, também chamenpm i @types/algo --save-dev
pra baixar as definições de tipo desse módulo -
Nao incluir a extensão em requires. Ex
import x = require('./utl/x')
-
Requires:
import x = require('x')
(troca o const por import)- ou sintaxe es6
import * as x from 'x'
import { readFile } from 'fs'
-
Exports usam sintaxe da proposta futura do js (não há objeto global
exports
):export var x = ...
export function y() { ... }
export = x
(export único)
-
TS = JS + tipos
-
Clique no ícone de X no canto inferior esquerdo do VS Code pra ver erros de tipagem
-
Erros de tipagem não interrompem a compilação. É tipo um linter! Ainda vai ser gerado o arquivo .js.
-
Abuso do CTRL(CMD) + click em variáveis e tipos. A inspeção de tipos te poupa de usar o debugger
-
Como especificar tipos pra variáveis:
var a : { b : string }
//ou
type TipoA = { b: string }
var a : TipoA
//ou
interface TipoA { b : string } //"interface" aceita extends. No fim gera a mesma coisa
var a : TipoA
//funções
type callback = (i:number) => Promise<any>
function ( a:string , cb:callback ) : number { ... }
var fn = ( a, b ) : number => { ... }
GOTCHAS
- Não especificar tipo == inferir tipo.
var a = { b : '3' } // a tem tipo { b : string }
var a = <any>{ b : 3 } //a tem tipo any
var a : number = <any>{ b : 3 } //a tem tipo number
var a : number = { b : 3 } //erro
var f = inp => 33 //f tem tipo (a:any) => number
Observe que você pode controlar os pontos de inferência de tipo de acordo com os tipos que estão definidos ou não. Ex: retornos de função, etc...
- Uma variável sempre terá um único tipo durante a sua existência
//common pitfall
var a = { b : 3 } //tipo definido por inferência
a.c = false //erro: c não está no tipo que foi inferido pra 'a'
Pra adicionar propriedades por partes (de forma imperativa) a um objeto, ou essas devem já estar declaradas no tipo dele, ou a sua tipagem deve estar desligada (ou ainda, defina o objeto de saída de uma vez só, não por partes). Propriedades podem ser definidas como opcionais:
var inst = {}
inst.a = 2 //erro
interface Tipo {
a? : number
}
var inst : Tipo = {}
inst.a = 2 //OK
var inst : any = {}
inst.a = 2 //OK
var a = 2
var inst = { a } //ok, melhor forma
- Desligar a tipagem
A checagem de tipo é desligada em uma variável atribuindo-se o tipo any
.
(<any>a).b.c.d = 55 //não dá erro
- Outras coisas
Você pode atribuir um tipo a uma variável não declarada no arquivo (uma variável global) usando declare
.
declare var $ : JQueryType //não inclui nada a mais no código gerado, apenas define a existência pro compilador
Assim como variáveis, tipos são exportáveis. export type A = { item : express.Request }
.
Caso útil, tipos globais podem ser declarados em um arquivo com extensão .d.ts
(neste caso, não use export para ter um tipo global).
Você pode importar um módulo só pra usar um tipo dele. O compilador verifica se há algum uso "concreto" dele e não inclui esse require no arquivo compilado se ele não for usado.
import express = require('express')
var a : express.RequestHandler = ( req, res, next ) => { ... }
//se express não for usado, não será incluído no arquivo compilado
- Generics
Definições de tipos, classes, funções e etc aceitam generics, daquele jeitão generics de ser. A inferência de tipos até que
faz malabarismos legais quando os tipos possuem generics. Nos outros casos, quando a relação de tipos de
algo se tornar complicada de definir, você vai provavelmente decidir melhor deixar any
por hoje mesmo.
type Tipo<K,V> = { a : K, b : V }
Um exemplo legal do uso do generics são os elementos do React.
//a assinatura é algo assim
var React : {
createElement<C<Props,State>, Props, State>( clas: C, props?: Props, state?: State ) : ReactElement
}
class Componente extends React.Component<{id:string, label:string},any> { ... }
var a = React.createComponent( Component, { label: 'legal' } ) //erro: falta o atributo obrigatório id
//ou com TSX
var a = <Component label='legal'/> //trás o mesmo erro
O que mais vou dizer? Programem como sempre. Não é porque está usando typescript que
tem que usar classes (eu não as apresentei aqui de propósito). Tenta usar a ferramenta
como um auxílio a mais de segurança de código. Lembre-se que a tipagem é opcional (através
do uso do any
). Você decide a cada ponto se é melhor gastar um tempinho a mais definindo
um tipo ou deixar sem validação porém perder possíveis detecções de erros.