É uma linguagem totalmente baseada em Javascript. Ela adiciona as tipagens e acessar as features mais recentes do Javascript no Node ou no browser. Ajuda muito no ambiente de desenvolvimento para criação e manutenção do código. IntelliSense do editor de código já consegue entender o formato da variável.
Criando um projeto backend em Typescript.
mkdir typescript
cd typescript
yarn init -y
yarn add typescript -D
Criar um arquivo src/index.ts
. E já dá para usar o Javascript mais recente, incluindo import
que ainda não é aceito no Node v.12.
Adicionar o pacote express
yarn add express
No arquivo index.ts
, ao importar o express
o VSCode já avisa que precisa instalar também o pacote @types/express
yarn add -D @types/express
Agora já conseguimos utilizar o express
no arquivo index.ts
e o Intellisense já entende.
import express from 'express'
const app = express()
app.get('/', (request, response) => {
return response.json({ message: 'Hello World' })
})
app.listen(3333)
Mas como o Node não entende Typescript, então é preciso converter o index.ts
em index.js
antes de executá-lo.
Para isso, vamos usar o pacote typescript
que já vem com um binário dentro de node_modules/.bin
.
Rodar:
yarn tsc src/index.ts
E criou um index.js
, mas deu um erro.
Assim como babel, temos que criar um arquivo tsconfig.json
com algumas configurações padrão
yarn tsc --init
Agora não precisa mais indicar qual o arquivo .ts
que você quer converter em .js
. É só colocar no terminal que ele já acha todos arquivos .ts
do projeto, sem dar erro.
yarn tsc
E agora podemos rodar o Node
node src/index.js
E podemos acessar no browser localhost:3333
Deleta o arquivo src/index.js
e no tsconfig.json
descomenta a seguinte informação e adiciona dist
:
{
"outDir": "./dist",
}
E roda de novo yarn tsc
para ser criado então os arquivos de dentro da dist
iguais ao da src
.
Quando criar tipagem?
Como instalamos o @types/express
, temos as tipagens já do express
.
Ao passar o mouse em cima do 'express'
e dar Cmd + click
, abre-se um arquivo index.d.ts
que traz a tipagem de cada variável do express
.
Arquivos com extensão .d.ts
significa que são arquivo de definição de tipagem.
Tudo que usa de dentro da lib, no mesmo arquivo, não precisa tipar pois o VSCode entende. Quando vamos para outro arquivo onde não está sendo chamado o express
por exemplo, que o VSCode se perde na tipagem.
Vamos separar a função de retorno da rota get criando um arquivo src/routes.ts
export function helloWorld (request, response) {
return response.json({ message: 'Hello World' })
}
E as bibliotecas já exportam os tipos também. Então, é só importar os tipos e usá-los. E todos os métodos já ficam acessíveis, facilitando a manutenção do código.
import { Request, Response } from 'express'
export function helloWorld (request: Request, response: Response) {
return response.json({ message: 'Hello World' })
}
Dentro de src/services
temos conjuntos isolados (funções) que executam alguma regra de negócio e retornam um resultado.
Exemplo, um service
de criação de usuário CreateUser.ts
.
Para criar um usuário, iremos utilizar o name
, email
e password
.
export default function createUser(name = '', email: string, password: string) {
const user = {
name,
email,
password,
}
return user
}
E ao importar essa função em src/routes.ts
, o próprio VSCode avisa que está faltando parâmetro e ainda verifica se o tipo do parâmetro está correto.
import { Request, Response } from 'express'
import createUser from './services/CreateUser'
export function helloWorld (request: Request, response: Response) {
const user = createUser('Cintia', 'cintiafumi@gmail.com', '123456')
return response.json({ message: 'Hello World' })
}
Mas seria melhor se tivesse o nome de cada parâmetro. Então, faz-se a desestruturação dos parâmetros na função, mas agora o typescript se perde porque entende que está querendo mudar o nome da variável por outra. Então, é melhor criar uma variável separada, o que é chamado de interface
, que traz o tipo de um conjunto de informações.
interface CreateUserData {
name?: string;
email: string;
password: string;
}
export default function createUser({ name = '', email, password }: CreateUserData) {
const user = {
name,
email,
password,
}
return user
}
Sendo name?
opcional, por isso pode já deixar na função o parâmetro recebendo uma string vazia caso não receba esse parâmetro, senão virá como undefined.
E na hora que chama a função, já dá para ver cada propriedade que é esperada. E no console.log(user.)
também já é possível ver as propriedades de user
com Ctrl + space
.
import { Request, Response } from 'express'
import createUser from './services/CreateUser'
export function helloWorld (request: Request, response: Response) {
const user = createUser({
email: 'cintiafumi@gmail.com',
password: '123456',
})
console.log(user.password)
return response.json({ message: 'Hello World' })
}
Tipagem de um vetor
Ao adicionar techs
na criação de user,
const user = createUser({
email: 'cintiafumi@gmail.com',
password: '123456',
techs: ['Node.js', 'ReactJS', 'React Native'],
})
Podemos definir a tipagem do vetor da seguinte forma:
interface CreateUserData {
name?: string;
email: string;
password: string;
techs: Array<string>
}
Ou
techs: string[]
Mas ao adicionar um objeto dentro de techs:
const user = createUser({
email: 'cintiafumi@gmail.com',
password: '123456',
techs: [
'Node.js',
'ReactJS',
'React Native',
{ title: 'Javascript', experience: 100 },
],
})
Precisamos criar então a tipagem desse objeto:
interface TechObject {
title: string;
experience: number;
}
interface CreateUserData {
name?: string;
email: string;
password: string;
techs: Array<string | TechObject>
}