Funções e Classes
Aula 3 de 7
Arrow Functions Tipadas
// Sintaxe básica
const somar = (a: number, b: number): number => a + b;
// Inferência no retorno
const multiplicar = (a: number, b: number) => a * b;
// Void — função que não retorna valor
const log = (mensagem: string): void => {
console.log(mensagem);
};
// Callback tipado
type Callback = (erro: Error | null, dados?: unknown) => void;
function buscarDados(url: string, cb: Callback) {
// ...
}
Function Overloads
// Sobrecargas (declarações)
function processar(valor: string): string[];
function processar(valor: number): number[];
function processar(valor: boolean): boolean;
// Implementação (mais genérica)
function processar(valor: string | number | boolean): unknown {
if (typeof valor === "string") return valor.split("");
if (typeof valor === "number") return Array.from(String(valor), Number);
return !valor;
}
// Uso
const arr = processar("abc"); // string[]
const nums = processar(123); // number[]
this Parameter
type Contexto = { nome: string };
function saudacao(this: Contexto) {
console.log(`Olá, ${this.nome}!`);
}
const ctx = { nome: "Alice" };
saudacao.call(ctx); // "Olá, Alice!"
// Erro: o this não tem o formato esperado
// saudacao.call({});
Classes
Modificadores de Acesso
class Animal {
public nome: string; // acesso público (padrão)
protected idade: number; // acesso na classe e subclasses
private especie: string; // acesso só na classe
constructor(nome: string, idade: number, especie: string) {
this.nome = nome;
this.idade = idade;
this.especie = especie;
}
public mover(): void {
console.log(`${this.nome} está se movendo.`);
}
}
class Cachorro extends Animal {
constructor(nome: string, idade: number) {
super(nome, idade, "Canino");
}
public latir(): void {
console.log(`${this.nome} diz: Au au!`);
// this.especie — Erro: private
}
}
readonly e static
class Configuracao {
static readonly VERSAO = "1.0.0";
static instancia?: Configuracao;
readonly id: string;
private static contador = 0;
constructor() {
this.id = `cfg-${Configuracao.contador++}`;
}
static criar(): Configuracao {
if (!this.instancia) {
this.instancia = new Configuracao();
}
return this.instancia;
}
}
console.log(Configuracao.VERSAO);
const cfg = Configuracao.criar();
Parameter Properties
Sintaxe concisa que declara e inicializa props no próprio construtor:
class Usuario {
constructor(
public readonly id: number,
public nome: string,
private email: string,
protected role: string = "user",
) {}
get contato(): string {
return this.email;
}
set contato(valor: string) {
if (!valor.includes("@")) throw new Error("Email inválido");
this.email = valor;
}
}
const user = new Usuario(1, "Alice", "[email protected]");
console.log(user.nome);
// user.id = 2; // Erro: readonly
Classes Abstratas
abstract class Forma {
abstract calcularArea(): number;
descrever(): string {
return `Área: ${this.calcularArea()}`;
}
}
class Circulo extends Forma {
constructor(private raio: number) {
super();
}
calcularArea(): number {
return Math.PI * this.raio ** 2;
}
}
// const forma = new Forma(); // Erro: não pode instanciar classe abstrata
const circulo = new Circulo(5);
console.log(circulo.descrever());
implements
interface Repositorio<T> {
buscar(id: string): Promise<T | null>;
salvar(item: T): Promise<void>;
deletar(id: string): Promise<boolean>;
}
class RepositorioUsuario implements Repositorio<Usuario> {
async buscar(id: string): Promise<Usuario | null> {
// implementação
return null;
}
async salvar(item: Usuario): Promise<void> {
// implementação
}
async deletar(id: string): Promise<boolean> {
return true;
}
}
Method Override
class Base {
protected dados: string[] = [];
executar(): void {
console.log("Base executando...");
}
}
class Derivada extends Base {
// Override: substitui método da classe pai
executar(): void {
console.log("Derivada executando antes...");
super.executar(); // chama implementação da Base
console.log("Derivada executando depois...");
}
}
Lab: Sistema de Classes
abstract class Funcionario {
constructor(
public readonly id: number,
public nome: string,
protected salario: number,
) {}
abstract calcularBonus(): number;
aumentarSalario(percentual: number): void {
this.salario += this.salario * (percentual / 100);
}
}
class Desenvolvedor extends Funcionario {
calcularBonus(): number {
return this.salario * 0.1;
}
}
class Gerente extends Funcionario {
calcularBonus(): number {
return this.salario * 0.2;
}
}
const dev = new Desenvolvedor(1, "Alice", 8000);
const gerente = new Gerente(2, "Bob", 15000);
console.log(dev.calcularBonus()); // 800
console.log(gerente.calcularBonus()); // 3000
npx tsc --noEmit
Classes abstratas definem contratos com implementação parcial.
implementsforça uma classe a seguir um contrato de interface. Parameter properties reduzem boilerplate no construtor.