Você adiciona um tipo após um dois-pontos. TypeScript pode inferir muitos tipos, então você anota onde isso adiciona clareza ou onde a inferência não é possível.
ts
// variables — usually let inference work
let count: number = 0; // explicit
let name = "Ann"; // inferred as string (annotation redundant)
// function parameters — always annotate (can't be inferred)
function greet(name: string, times: number): string {
return name.repeat(times);
}
// arrays and objects
const ids: number[] = [1, 2, 3];
const user: { name: string; age: number } = { name: "Ann", age: 30 };
Tipos de retorno: inferir ou anotar?
ts
function add(a: number, b: number) { return a + b; } // inferred return: number
function load(): Promise<User> { ... } // explicit — documents the contract
Os tipos de retorno são inferidos, mas anotá-los em funções exportadas/públicas é uma boa prática: documenta a intenção e captura erros dentro da função (se você acidentalmente retorna algo incorreto, o erro aponta para a função, não para seus chamadores).
Casos especiais
ts
function log(msg: string): void {} // returns nothing
function fail(): never { throw new Error(); } // never returns normally
const fn: (x: number) => string = ...; // function type annotation
Por que isso importa
A regra prática: anote assinaturas de função (parâmetros e tipos de retorno públicos) explicitamente, deixe as variáveis locais serem inferidas. Isso mantém o código conciso enquanto deixa os contratos nos limites das funções claros e verificados.
