Skip to content

Instantly share code, notes, and snippets.

@wkrueger
Last active October 17, 2016 13:39
Show Gist options
  • Save wkrueger/5caeada42f9bad51ed633d337d37a3dd to your computer and use it in GitHub Desktop.
Save wkrueger/5caeada42f9bad51ed633d337d37a3dd to your computer and use it in GitHub Desktop.
A typescript 2 + node.js quick n dirty start

A typescript 2 + node.js quick n dirty start

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.

Você vai precisar

  • 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 comando tsc --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 (ou F1 e digitar "build") > Configure Task Runner > Typescript - Watch Mode. Salve o arquivo criado.

  • CTRL + SHIFT + B novamente. (equivalente a chamar tsc -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 basta built.

Debug

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", apontar program 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.

Módulos

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 chame npm 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)

Introdução rápida e suja à linguagem

  • 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment