TypeScript: Tipos de função no TypeScript

Última atualização: 2026-08-26

As funções são um conceito fundamental do JavaScript, e o TypeScript adiciona um sistema de tipos abrangente aos parâmetros e valores de retorno das funções — garantindo que as “entradas” e “saídas” de uma função sejam claramente definidas.

1. Anotações de tipo de função

(1) Tipos de parâmetros e de valores de retorno

TYPESCRIPT
function add(a: number, b: number): number {
  return a + b;
}

let result = add(1, 2);    // result Inferred as number
// add("1", "2");          // ❌ Parameter types do not match
// add(1);                 // ❌ Insufficient number of parameters

(2) Inferência do tipo de retorno

O TypeScript pode inferir o tipo de retorno com base na instrução return, mas recomenda-se especificá-lo explicitamente:

TYPESCRIPT
// Return Type Inference——Can be inferred, but not recommended(It's easy to make mistakes when deriving large functions)
function multiply(a: number, b: number) {
  return a * b;   // Inference Return number
}

// Explicit Annotation——Recommendations(Purpose of the Document + Compile-time errors)
function divide(a: number, b: number): number {
  if (b === 0) throw new Error("The divisor cannot be zero.");
  return a / b;
}

(3) void tipo de retorno

Use void quando uma função não tiver valor de retorno:

TYPESCRIPT
function log(message: string): void {
  console.log(message);
  // None return Statement,Or return; —— All of them void
}

(4) nunca retorna um valor

Use never quando uma função nunca retornar um valor — ela lançará uma exceção ou entrará em um laço infinito:

TYPESCRIPT
function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) { }
}
Tipo de retorno Significado
void A função foi executada normalmente, mas não retornou um valor
never A função nunca termina (lança uma exceção ou entra em um laço infinito)

▶ Exemplo: Funções utilitárias tipadas

TYPESCRIPT
function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max);
}

function formatCurrency(amount: number, symbol: string = "¥"): string {
  return symbol + amount.toFixed(2);
}

console.log(clamp(150, 0, 100));           // 100
console.log(clamp(-5, 0, 100));            // 0
console.log(clamp(50, 0, 100));            // 50
console.log(formatCurrency(99.5));         // ¥99.50
console.log(formatCurrency(42, "$"));      // $42.00
▶ Experimente

Saída:

TEXT 📖 Somente leitura
100
0
50
¥99.50
$42.00


2. Parâmetros opcionais e parâmetros padrão

(1) Parâmetro opcional ?

TYPESCRIPT
function greet(name: string, title?: string): string {
  if (title) {
    return `${title} ${name}`;
  }
  return `Hello,${name}`;
}

console.log(greet("Charlie"));           // "Hello,Charlie"
console.log(greet("Charlie", "Engineer"));  // "Engineer Charlie"
⚠️ Regra: Os parâmetros opcionais devem vir após os parâmetros obrigatórios. function greet(title?: string, name: string) resultará em um erro.

(2) Parâmetros padrão

TYPESCRIPT
function createUser(name: string, role: string = "viewer", active: boolean = true): string {
  return `${name},Characters:${role},${active ? "Active" : "Not activated"}`;
}

console.log(createUser("Charlie"));                       // Charlie,Characters:viewer,Active
console.log(createUser("Diana", "editor"));             // Diana,Characters:editor,Active
console.log(createUser("Eric", "admin", false));       // Eric,Characters:admin,Not activated

(3) Parâmetros opcionais x parâmetros padrão

Recurso Parâmetro opcional title?: string Parâmetro padrão role: string = "viewer"
Quando chamado Opcional; o valor é indefinido Opcional; o valor é o padrão
Tipo string | undefined string (não a união indefinida)
Recomendação O valor pode, de fato, ser indefinido Na maioria dos casos, é melhor definir um valor padrão razoável


3. Parâmetros restantes

Use a sintaxe ... para reunir os parâmetros restantes em uma matriz:

TYPESCRIPT
function sum(first: number, ...rest: number[]): number {
  return rest.reduce((total, n) => total + n, first);
}

console.log(sum(1));             // 1
console.log(sum(1, 2));         // 3
console.log(sum(1, 2, 3, 4));   // 10

(1) Os demais parâmetros devem ser do tipo array

TYPESCRIPT
function logAll(prefix: string, ...messages: string[]): void {
  messages.forEach(msg => console.log(`${prefix}: ${msg}`));
}

logAll("DEBUG", "Start the service", "Connect to the Database", "Ready");

Saída:

TEXT 📖 Somente leitura
DEBUG: Start the service
DEBUG: Connect to the Database
DEBUG: Ready


4. Expressões do tipo função

As funções também podem ser passadas por valor — nesse caso, utiliza-se uma expressão de tipo de função para especificar o tipo:

(1) Os aliases de tipo definem tipos de função

TYPESCRIPT
type MathOperation = (a: number, b: number) => number;

let add: MathOperation = (a, b) => a + b;
let subtract: MathOperation = (a, b) => a - b;
let multiply: MathOperation = (a, b) => a * b;

console.log(add(10, 5));       // 15
console.log(subtract(10, 5));  // 5
console.log(multiply(10, 5));  // 50

(2) Tipos de funções de retorno de chamada

O uso mais comum dos tipos de função — descrever a assinatura de uma função de retorno de chamada:

TYPESCRIPT
function fetchData(url: string, onSuccess: (data: string) => void, onError: (error: Error) => void): void {
  // Simulating Asynchronous Operations
  if (url.startsWith("https://")) {
    onSuccess("Data loaded successfully");
  } else {
    onError(new Error("Supports only HTTPS"));
  }
}

fetchData(
  "https://api.example.com",
  data => console.log(data),         // ✅ (data: string) => void
  error => console.log(error.message) // ✅ (error: Error) => void
);

(3) Definição de tipos de função por meio de interfaces

TYPESCRIPT
interface Comparator {
  (a: number, b: number): number;
}

let ascending: Comparator = (a, b) => a - b;
let descending: Comparator = (a, b) => b - a;

let nums = [3, 1, 4, 1, 5];
console.log([...nums].sort(ascending));   // [1, 1, 3, 4, 5]
console.log([...nums].sort(descending));  // [5, 4, 3, 1, 1]


5. Sobrecarga de funções

A sobrecarga de funções permite que um único nome de função suporte diferentes combinações de tipos de argumentos — a sobrecarga no TypeScript segue o padrão “declaração + implementação”:

(1) Sintaxe básica

TYPESCRIPT
// Overloaded Signatures——Describe the return type for each parameter combination
function format(value: number): string;
function format(value: string): string;
function format(value: Date): string;

// Implementing Signatures——Must be compatible with all overloaded signatures
function format(value: number | string | Date): string {
  if (typeof value === "number") {
    return value.toFixed(2);
  } else if (typeof value === "string") {
    return value.trim();
  } else {
    return value.toISOString();
  }
}

console.log(format(3.14));             // "3.14"
console.log(format("  hello  "));      // "hello"
console.log(format(new Date()));       // "2024-..."

(2) Ordem de sobrecarga

O TypeScript compara métodos sobrecarregados na ordem em que são declarados, de cima para baixo — portanto, as sobrecargas mais específicas devem ser colocadas primeiro:

TYPESCRIPT
// ✅ Correct Order——The specifics come first
function process(value: string): string;
function process(value: any): unknown;

// ❌ Incorrect Order——any Matches all parameters,The overloaded version that comes later will never be called.
// function process(value: any): unknown;
// function process(value: string): string;

▶ Exemplo: Sobrecarga para implementar o tratamento de eventos com segurança de tipos

TYPESCRIPT
function on(event: "click", handler: (x: number, y: number) => void): void;
function on(event: "keydown", handler: (key: string) => void): void;
function on(event: string, handler: Function): void {
  console.log(`Registration Event:${event}`);
  // Implementation details omitted...
}

// Automatically determines the correct parameter types upon invocation
on("click", (x, y) => {
  console.log(`Click here:(${x}, ${y})`);   // x, y Inferred as number
});

on("keydown", (key) => {
  console.log(`Press the button:${key}`);           // key Inferred as string
});
▶ Experimente

Saída:

TEXT 📖 Somente leitura
// Executed successfully


6. Tipos de funções-seta

(1) Anotações de tipo para funções-seta

TYPESCRIPT
const add = (a: number, b: number): number => a + b;

// When acting as a callback,Parameter types can usually be inferred
const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2);       // n Inferred as number
const asStrings = nums.map(n => String(n)); // n Inferred as number

(2) Funções-seta e this

As funções-seta não definem seu próprio this — elas herdam o this externo:

TYPESCRIPT
class Timer {
  seconds = 0;

  start() {
    // Arrow Functions——this Orientation Timer Examples
    setInterval(() => {
      this.seconds++;
      console.log(`${this.seconds}s`);
    }, 1000);
  }

  startBroken() {
    // Ordinary Functions——this Points to the global or undefined(Strict Mode)
    setInterval(function () {
      // this.seconds++;  // ❌ Runtime this No Timer
    }, 1000);
  }
}


▶ Exemplo: Parâmetros restantes e sobrecarga de funções

TYPESCRIPT
// Rest parameters — collecting variable arguments
function log(context: string, ...messages: string[]): void {
  console.log(`[${context}] ${messages.join(", ")}`);
}

log("App", "started", "initialized", "ready");
// [App] started, initialized, ready

// Function overloads — different return types per signature
function parse(input: string): Date;
function parse(input: number): Date;
function parse(input: string | number): Date {
  return typeof input === "string"
    ? new Date(input)
    : new Date(input);
}

let fromStr = parse("2024-01-01");
let fromNum = parse(1704067200000);
console.log(fromStr.toISOString());  // "2024-01-01T00:00:00.000Z"
▶ Experimente

Saída:

TEXT 📖 Somente leitura
[App] started, initialized, ready
2024-01-01T00:00:00.000Z

❓ Perguntas Frequentes

P: Os tipos de retorno das funções devem ser especificados explicitamente? R: Recomenda-se especificá-los. Embora o TypeScript possa inferi-los, a especificação explícita oferece três benefícios: (1) Documentação — o tipo de retorno fica imediatamente claro; (2) Prevenção contra o retorno acidental do tipo errado; (3) Melhor localização de erros — os erros são relatados na assinatura da função, em vez de no ponto de chamada. É possível omitir o tipo de retorno para funções curtas (de uma única linha return), mas recomenda-se especificá-lo para funções com mais de três linhas.

P: Qual é a diferença entre os tipos de retorno void e undefined? R: void significa que “a função não se preocupa com o valor de retorno” — a função pode ou não ter uma instrução return, e quem a chama não deve usar o valor de retorno. undefined é um tipo específico — a função retorna explicitamente undefined. No desenvolvimento prático, todas as funções sem valor de retorno utilizam void.

P: Qual é a diferença entre sobrecarga de funções e parâmetros de tipo união? R: Um tipo união function fn(x: string | number) apenas indica que “um parâmetro pode ser um desses tipos”, mas todas as combinações de parâmetros retornam o mesmo tipo. A sobrecarga permite que “diferentes combinações de parâmetros retornem tipos diferentes” — algo que os tipos de união não conseguem fazer. Se os tipos dos parâmetros forem flexíveis, mas o tipo de retorno for uniforme, usar um tipo de união é mais conciso; use a sobrecarga quando forem necessários tipos de retorno diferentes.

P: É possível usar parâmetros padrão e parâmetros opcionais juntos? R: Não. function fn(x?: string = "hi") é um erro de sintaxe — os parâmetros padrão já são considerados “opcionais” por definição, portanto não há necessidade de adicionar ?. x: string = "hi" é equivalente a x?: string, mas seu valor é “hi” em vez de indefinido.

📖 Resumo

📝 Exercícios

  1. Exercício básico (Dificuldade ⭐): Escreva três funções — add(a, b) para adição, subtract(a, b) para subtração e multiply(a, b) para multiplicação — nas quais tanto os parâmetros quanto os valores de retorno sejam do tipo number. Use expressões do tipo função para declarar os tipos de maneira uniforme.
  2. Problema avançado (Dificuldade ⭐⭐): Escreva uma função buildQuery(params: Record<string, string | number | boolean>) que converta um objeto em uma string de consulta de URL. Por exemplo, { page: 1, size: 10, active: true }"page=1&size=10&active=true".
  3. Desafio (Dificuldade ⭐⭐⭐): Implemente isso usando sobrecarga de funções createElement(tag, props): quando a tag for “input”, os props devem ser type: string; quando a tag for “a”, os props devem ser href: string; e quando a tag for “div”, os props são um objeto genérico. Retorne um objeto de descrição de tipo diferente para cada caso.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%