Os tipos do TypeScript descrevem que tipo de valor uma variável pode guardar. Você escreve o tipo depois de dois pontos, let name: string, e o compilador rejeita qualquer código que coloque ali um valor do tipo errado. Os tipos básicos são os sete primitivos do JavaScript mais os tipos de objeto para arrays e objetos.
As anotações são verificadas em tempo de compilação e depois removidas. O programa que roda é JavaScript puro.
Os tipos primitivos
| Tipo | Valores de exemplo | Observações |
|---|---|---|
string | "hi", 'hi', `hi ${name}` | Texto. Os três estilos de aspas têm o mesmo tipo. |
number | 42, 3.14, -0.5, NaN, Infinity | Todo número, inteiro ou não. Não existe int nem float. |
boolean | true, false | Só esses dois valores. |
bigint | 10n, BigInt(10) | Inteiros de qualquer tamanho. Exige target ES2020 ou superior. |
symbol | Symbol("id") | Um valor único, usado principalmente como chave de objeto. |
null | null | "Vazio de propósito". |
undefined | undefined | "Não definido". Também é o que uma propriedade ausente retorna. |
Os nomes dos tipos são minúsculos. Em tempo de execução, typeof retorna as mesmas palavras para a maioria deles, então typeof x === "number" é a forma de verificar o tipo primitivo de um valor enquanto o programa roda.
Anotações de tipo
Uma anotação é : Type depois de uma variável, de um parâmetro ou da lista de parâmetros de uma função. Os parâmetros são onde as anotações mais importam, porque o TypeScript não tem como adivinhar o que quem chama vai passar.
Quando a variável é inicializada na mesma linha, a anotação costuma ser redundante: let count = 10 já tem o tipo number. As regras para omitir tipos estão na página de inferência de tipos.
Um tipo errado é um erro de compilação
Atribua um valor do tipo errado e o compilador para antes de qualquer coisa rodar:
O compilador mostra:
index.ts(3,1): error TS2322: Type 'string' is not assignable to type 'number'.
A correção é converter o valor, port = Number("3000"), ou mudar a anotação se a variável realmente deve guardar texto.
number: não existe tipo inteiro
O JavaScript guarda todo número como um valor de ponto flutuante de 64 bits, por isso o TypeScript tem um único tipo number. Inteiros são exatos até Number.MAX_SAFE_INTEGER (2 ** 53 - 1). Acima disso, use bigint.
bigint e number não se misturam: exact + 1 é um erro de compilação (TS2365: Operator '+' cannot be applied to types 'bigint' and '1'., em que '1' é o tipo literal do 1) e, se chegasse a rodar, também seria um TypeError em tempo de execução. Converta um dos lados explicitamente com BigInt(1) ou Number(exact), sabendo que Number arredonda valores fora da faixa segura.
Se você quer um tipo que aceite só números inteiros, o TypeScript não consegue expressar isso para valores arbitrários. Valide com Number.isInteger no ponto em que o valor entra no seu programa.
boolean
boolean tem exatamente dois valores, true e false. Valores que são apenas truthy (1, "yes") não são booleanos, então converta-os com Boolean(x) ou x !== 0.
null e undefined
Com strict ativado (o padrão desde o TypeScript 6.0), null e undefined são tipos separados e não fazem parte de string, number nem de nenhum outro tipo. Uma variável que pode estar vazia declara isso com uma union:
Ler uma propriedade de um valor que pode ser undefined é um erro de compilação até você fazer a verificação. A página de null e undefined explica as verificações, ?. e ??.
Arrays e objetos em resumo
Tudo o que não é primitivo é um tipo de objeto. As três formas que você encontra primeiro:
let tags: string[] = ["ts", "js"]; // array of strings
let point: { x: number; y: number } = { x: 1, y: 2 }; // object with two number properties
let greet: (name: string) => string = (n) => `hi ${n}`; // function type
Cada uma tem sua própria página: arrays, tuplas (arrays de tamanho fixo), tipos de objeto e tipos de função.
string, number, boolean vs String, Number, Boolean
Os nomes com inicial maiúscula são os tipos dos objetos wrapper do JavaScript (new String("x")), não dos valores comuns. Anote com os nomes minúsculos.
index.ts(3,7): error TS2322: Type 'String' is not assignable to type 'string'.
'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.
Troque String por string na primeira linha e o bloco roda. O mesmo vale para Number, Boolean, Symbol e BigInt. (Object é outro caso: aceita quase qualquer valor, primitivos incluídos; veja tipos de objeto.)
Outros tipos nativos
Mais alguns tipos aparecem logo no começo. Cada um tem sua própria página.
| Tipo | Significado |
|---|---|
any | Desliga a verificação para aquele valor. Evite. |
unknown | Qualquer valor, mas você precisa verificá-lo antes de usar. |
void | A função não retorna nada útil. |
never | Nenhum valor: uma função que sempre lança exceção, ou um caso impossível. |
object | Qualquer valor não primitivo. |
"red" | "green" | Um tipo literal: só esses valores exatos. |
Perguntas frequentes
O TypeScript tem um tipo inteiro?
Não. number cobre tanto inteiros quanto decimais, porque o JavaScript guarda todo número como um float de 64 bits. Verifique se é um número inteiro em tempo de execução com Number.isInteger(n) e use bigint (10n) quando precisar de inteiros maiores que Number.MAX_SAFE_INTEGER (2 ** 53 - 1) sem perder precisão.
Qual é a diferença entre string e String no TypeScript?
string é o tipo primitivo, que é o tipo dos literais de string e das template strings. String é o tipo do objeto wrapper criado por new String("x"). Anote sempre com as formas minúsculas string, number e boolean; atribuir um String a um string é um erro de compilação (TS2322).
Quais são os tipos primitivos do TypeScript?
Os mesmos sete do JavaScript: string, number, boolean, bigint, symbol, null e undefined. Todo o resto (arrays, objetos, funções, instâncias de classe) é um tipo de objeto.
Como declarar uma variável com tipo no TypeScript?
Coloque dois pontos e o tipo depois do nome: let count: number = 0;. Em uma função, anote cada parâmetro e, se quiser, o tipo de retorno: function add(a: number, b: number): number. Quando a variável é inicializada, em geral dá para omitir a anotação e deixar o TypeScript inferir o tipo.
Os tipos do TypeScript existem em tempo de execução?
Não. O compilador verifica os tipos e depois os remove, então o JavaScript que roda não tem anotações. Em tempo de execução você verifica valores com operadores do JavaScript como typeof, Array.isArray e instanceof.