-
-
Save reginadiana/c92609d5e31b152351d1d8d49d3fa5c1 to your computer and use it in GitHub Desktop.
É um recurso desenvolvido pela empresa Microsoft em 2012, sendo ele um superconjunto de recursos já existentes no javascript que seriam bem complexos de se desenvolver nativamente. Como:
❤️ Tipagem explicita, ou seja, todos os tipos são e devem ser declarados no código;
❤️ Orientação a objetos
❤️ Permitir que sites e aplicativos sejam executados tanto no lado do cliente como no servidor com o Node.js
❤️ O código em typescript é tranformado (transcompilado) para javascript puro antes de ser executado pelo navegador.
❤️ Usamos a extensão .ts
e .tsx
para componentes React
❤️ Também é possível usar com outros compiladores que suportam a linguagem como Babel
❤️ Temos todas as funcionalidades do javascript acrescidas dos recursos do typescript
❤️ Não precisamos ficar adivinhando o tipo das coisas e o vscode nos ajuda nisso. Podemos massar o mouser por cima que ele poderá dar os tipos. Assim, podemos copiar e colar para as nossas interfaces
❤️ Podemos adicionar o comentário //@ts-check em um arquivo ts para vermos os avisos do typescript.
❤️ O ts não pode ser compilado diretamente pelo browser, precisamos de um compilador (ex: babel) para transformar em js
❤️ O comando tsc --init vai gerar o arquivo tsconfig.json com as configurações do typescript.
target: define qual versão do javascript o código será compilado
ES3: versão bem antiga do javascript
ESNext: versão mais recente
strict: define várias configurações em cadeira. Ex: os dados devem ter uma tipagem explicita
Comando ts -w compila com watch
Annotation: é o ato de descrever qual tipagem um objeto, variável, etc, tem
Inference ("implicity"): é o ato de inferir (deduzir) qual é tipo das coisas. É uma boa prática não declarar o tipo quando o ts não solicita pois já inferiu, seria redundante.
runtime: em execução
Ao declarar uma variável, precisamos deixar explicito o tipo dela (number
, string
, boolean
, etc)
Dentro desses tipos de variáveis também podemos encontrar o any
, que é um tipo que pode ser modificado para qualquer outro tipo presente na linguagem, seja string
, number
ou qualquer outra coisa.
Sem adicionar nenhuma indicação de tipo, as variáveis no typescript são do tipo any
, o que significa que elas podem conter qualquer tipo de dados, assim como o js.
Arrays são um caso comum de tipos genéricos.
Se uma função for jogada (throw
), ela terá um tipo never.
O unknown é um tipo de contrapartida segura do any
, garantindo que alguma verificação de tipo seja executada antes que o valor possa ser usado. É melhor usado quando voce não sabe o tipo do dado a ser tipado. Para adicionar um tipo depois, voce vai precisar usar o cast.
Funções que não retornam nada, apenas executam
O typeof
permite com que façamos uma "cópia" da declaração de um tipo de uma variável para outra. Podemos usar uma interface para ter mais ou menos esse mesmo efeito, mas de forma nomeada. Por exemplo:
interface Point {
x: number;
y: number;
}
let point: Point;
let point2: Point;
Essa alteração permite que o tipo Point
seja usado em vários locais dentro do código sem precisar redefinir os detalhes do tipo repetias vezes.
A ordem da declaração dessas funções importa para o que o typescript possa escolher sobre qual o value mais se corresponde ao tipo declarado em cada uma delas.
function numberStringSwap(value: number, radix?: number): string;
function numberStringSwap(value: string): number;
function numberStringSwap(value: any, radix: number = 10): any {
if (typeof value === 'string') {
return parseInt(value, radix);
}
else if (typeof value === 'number') {
return String(value);
}
}
number
array
string
boolean
any
unknown
tuple
enum
null
undefined
void
Casting é o processo de sobrescrever um tipo usando as chaves as
ou <>
. Exemplo:
let x: unknown = 'hello'; // Aqui a variável x é do tipo desconhecida
console.log((<string>x).length); // Mas aqui estamos usando o casting (as) para dizer que agora é do tipo string, sobrescrevendo seu tipo.
Vale lembrar, que o casting só vai funcionar se a variável tiver um tipo anterior. Ou seja, se usarmos o valor diretamente no lugar na variável vamos ter um erro.
A chave readonly
pode prevenir arrays de serem mudados
const car: {type: string, mileage?: number } = {
type: "Toyota"
}
Enum
representa um grupo de constantes
É possível misturar e dar match em enum values de string
e numeros, mas não é recomendável.
// the : number here specifies that this function returns a number
function getTime(): number {
return new Date().getTime();
}
Por padrão, o typescript vai assumir que todos os parametros são obrigatórios, mas eles podem ser marcados como opcionais.
/* O operador ? vai fazer o parametro c ser opcional */
function add(a: number, b: number, c?: number) {
return a + b + (c || 0);
}
Exemplo sobre como definir um valor padrão para um parametro. O typescript pode atribuir o tipo de acordo com o valor passado.
function pow(value: number, exponent: number = 10) {
return value ** exponent;
}
// Desestruturação de parametros na função
function divide({ dividend, divisor }: { dividend: number, divisor: number }) { ... }
Parametros Rest podem ser enviados, mas o tipo deve ser sempre um array.
// rest é um array de números. [] indica que é um array
function add(a: number, b: number, ...rest: number[] {
return a + b + rest.reduce((p, c) => p + c, 0)
}
- Quando voce está escrevendo um código typescript que precisa acessar as declarações de ambiente, um comentário de referencia especial deve ser adicionado ao tipo do módulo que precisa dele.
interface Point {
x: number;
y: number;
}
let pointPart: Partial<Point> = {};
O fato de não declararmos o tipo da variável explicitamente não significa que ela não possui um tipo, mas este será dado pelo compilador de acordo com o valor que ela possui
Optional Chaining é uma feature do js que trabalha bem lidando com valores nulos. Ele permite acessar propriedades em um objeto, que podem ou não existir de forma compacta. Exemplo: house.yard?.sqft
Nullish Coalescence é outra feature do js que também trabalha bem lidando com o null do typescript. Ele permite escrever expressões que tem um fallback especifico quando lida com o null ou undefined. Isso é util quando valores falsos ocorrerem na expressão mas ainda for válido.
function createPair<S, T>(v1: S, v2: T): [S, T] {
return [v1, v2]
}
console.log(createPair<string, number>('hello', 42)); // ['hello', 42]
É bem comum que os componentes recebam a props children
, que recebemos dessa forma:
import { ReactNode } from 'react';
type Props = {
children: ReactNode;
};
function Component({ children }: Props) {
return (
<div>
{children}
</div>
);
}
export default Component;
Porém, podemos escrever de uma forma mais simplificada com PropsWithChildren e ter o mesmo efeito, porém com o children opcional e possivelmente undefined
:
import { PropsWithChildren } from 'react';
function Component({ children }: PropsWithChildren) {
return (
<div>
{children}
</div>
);
}
export default Component;
Existem casos onde temos um componente de design, como um input
, em que temos que passar várias propriedades referentes a ele. Podemos fazer isso de uma forma explicita:
import React from 'react'
type Props = {
label: string;
className: string;
onChange: () => void;
}
export default function Input({ label, className, onChange }: Props) {
return (
<div style={{ marginBottom: '1rem' }}>
<label htmlFor={label}>{label}</label>
<input className={className} onChange={onChange} type="text" id={label} name={label}></input>
</div>
)
}
Porém, podemos fazer isso de uma forma implicita e permitir que qualquer propriedade que seja atralada ao input
por padrão possa ser passado ao nosso componente, sem a necessidade de criar novas props a todo momento usando o ComponentProps
import React from 'react'
type Props = React.ComponentProps<'input'> & {
label: string
}
export default function Input({ label, ...rest }: Props) {
return (
<div style={{ marginBottom: '1rem' }}>
<label htmlFor={label}>{label}</label>
<input type="text" id={label} name={label} {...rest}></input>
</div>
)
}
import React, { useState } from 'react'
export default function Checkbox({ label }: { label: string }) {
const [checked, setChecked] = useState(false);
// Se deixarmos essa função anonima o typescript vai inferir
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setChecked(event.currentTarget.checked);
}
return (
<label>
<input type="checkbox" checked={checked} onChange={handleChange}/>
{label}
</label>
)
}