TypeScript: Classe do TypeScript (class)

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

As classes são um recurso de sintaxe orientado a objetos introduzido no JavaScript ES6. O TypeScript se baseia nisso ao adicionar anotações de tipo e controle de acesso — garantindo que as propriedades e os métodos das classes sejam restritos por tipo.

1. Sintaxe básica das classes

(1) Declarações de propriedades e construtores

O TypeScript exige que as propriedades das classes sejam declaradas antes de poderem ser utilizadas — ao contrário do JavaScript:

TYPESCRIPT
class User {
  // Property Declaration(TypeScript Requirements)
  name: string;
  age: number;

  // Constructor
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  // Methods
  greet(): string {
    return `Hello,I am${this.name},This year${this.age} years old`;
  }
}

let user = new User("Charlie", 20);
console.log(user.greet());  // "Hello,I amCharlie,This year20 years old"

(2) Várias maneiras de inicializar propriedades

TYPESCRIPT
class Config {
  // Method 1:Initialize directly upon declaration
  host: string = "localhost";
  port: number = 3000;

  // Method 2:Initialization in the Constructor
  env: string;

  constructor(env: string) {
    this.env = env;
  }

  // Method 3:Assert that it is not empty(!)——You promise to assign a value later.
  data!: string;
}

let cfg = new Config("development");
cfg.data = "some data";  // Create First, Then Assign
🔥 Erro comum: Se uma propriedade não for inicializada nem receber um valor no construtor, o TypeScript lançará um erro do tipo “propriedade não inicializada” (no modo estrito). É possível contornar isso usando a asserção !, mas certifique-se de que a propriedade realmente receba um valor.



2. Modificadores de acesso

Os três modificadores de acesso do TypeScript controlam a visibilidade das propriedades e dos métodos:

Modificador Dentro da classe Subclasse Fora da classe
public
protected
private

(1) público (padrão)

TYPESCRIPT
class Person {
  public name: string;   // public This is the default value.,Optional
  public age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

let p = new Person("Charlie", 20);
console.log(p.name);  // ✅ Accessible from outside the class
p.name = "Diana";      // ✅ Can be modified from outside the class

(2) privado

TYPESCRIPT
class BankAccount {
  private balance: number;

  constructor(initialBalance: number) {
    this.balance = initialBalance;
  }

  public deposit(amount: number): void {
    if (amount > 0) this.balance += amount;
  }

  public withdraw(amount: number): boolean {
    if (amount > 0 && amount <= this.balance) {
      this.balance -= amount;
      return true;
    }
    return false;
  }

  public getBalance(): number {
    return this.balance;
  }
}

let account = new BankAccount(1000);
account.deposit(500);
account.withdraw(200);
console.log(account.getBalance());  // 1300
// account.balance;                  // ❌ private The property is not accessible from outside
// account.balance = 99999;          // ❌ private Properties cannot be modified externally

(3) protegido

TYPESCRIPT
class Animal {
  protected name: string;

  constructor(name: string) {
    this.name = name;
  }

  protected makeSound(sound: string): void {
    console.log(`${this.name}:${sound}`);
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name);
  }

  public bark(): void {
    this.makeSound("Woof!");  // ✅ Subclasses can access protected Methods
    // console.log(this.name);  // ✅ Subclasses can access protected Properties
  }
}

let dog = new Dog("Wangcai");
dog.bark();           // "Wangcai:Woof!"
// dog.name;           // ❌ protected The property is not accessible from outside
// dog.makeSound("Howl"); // ❌ protected This method cannot be called from outside the class.

(4) Notação abreviada para parâmetros de construtor

O TypeScript oferece propriedades de parâmetro — ao adicionar modificadores antes dos parâmetros do construtor, ele declara e inicializa automaticamente as propriedades:

TYPESCRIPT
// Complete Syntax
class User1 {
  public name: string;
  private age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

// Abbreviation——The effect is exactly the same
class User2 {
  constructor(
    public name: string,
    private age: number
  ) {}
}

let u = new User2("Charlie", 20);
console.log(u.name);    // ✅ public
// console.log(u.age);  // ❌ private
💡 Dica: As propriedades dos parâmetros tornam o código mais conciso, mas a legibilidade diminui quando há muitas propriedades. Para três propriedades ou menos, use a notação abreviada; para mais de três, declare-as explicitamente.



3. Modificador readonly

readonly Propriedades com modificadores só podem receber valores no momento da declaração ou no construtor:

TYPESCRIPT
class Circle {
  readonly radius: number;

  constructor(radius: number) {
    this.radius = radius;  // ✅ You can assign values in the constructor
  }

  get area(): number {
    return Math.PI * this.radius ** 2;
  }
}

let circle = new Circle(5);
console.log(circle.area);     // 78.54
// circle.radius = 10;        // ❌ readonly Properties cannot be modified

(1) Propriedades readonly + parâmetros

TYPESCRIPT
class Config {
  constructor(
    readonly host: string,
    readonly port: number
  ) {}
}

let cfg = new Config("localhost", 3000);
console.log(`${cfg.host}:${cfg.port}`);  // "localhost:3000"
// cfg.host = "other";  // ❌ readonly


4. Acessadores (getters / setters)

Os acessadores permitem que você execute uma lógica personalizada ao ler ou gravar propriedades:

(1) Sintaxe básica

TYPESCRIPT
class Employee {
  private _salary: number = 0;

  // getter——Execute on read
  get salary(): number {
    return this._salary;
  }

  // setter——Perform validation during assignment
  set salary(value: number) {
    if (value < 0) {
      throw new Error("Salaries cannot be negative.");
    }
    this._salary = value;
  }
}

let emp = new Employee();
emp.salary = 8000;       // Call setter
console.log(emp.salary);  // Call getter → 8000
// emp.salary = -100;     // ❌ Throw an error

(2) Propriedades somente leitura (com um getter, mas sem setter)

TYPESCRIPT
class User {
  constructor(
    private firstName: string,
    private lastName: string
  ) {}

  get fullName(): string {
    return `${this.firstName} ${this.lastName}`;
  }
  // None setter → fullName It is read-only.
}

let user = new User("San", "Zhang");
console.log(user.fullName);  // "San Zhang"
// user.fullName = "Si Li";  // ❌ None setter

▶ Exemplo: Conversor de temperatura

TYPESCRIPT
class Temperature {
  private _celsius: number = 0;

  constructor(celsius: number) {
    this._celsius = celsius;
  }

  get celsius(): number {
    return this._celsius;
  }

  set celsius(value: number) {
    if (value < -273.15) {
      throw new Error("The temperature must not fall below absolute zero.(-273.15°C)");
    }
    this._celsius = value;
  }

  get fahrenheit(): number {
    return this._celsius * 9 / 5 + 32;
  }

  set fahrenheit(value: number) {
    this.celsius = (value - 32) * 5 / 9;  // Reuse celsius Verification of
  }
}

let temp = new Temperature(100);
console.log(`${temp.celsius}°C = ${temp.fahrenheit}°F`);  // "100°C = 212°F"

temp.fahrenheit = 32;
console.log(`${temp.celsius}°C = ${temp.fahrenheit}°F`);  // "0°C = 32°F"
▶ Experimente

Saída:

TEXT 📖 Somente leitura
100°C = 212°F
0°C = 32°F


5. Membros estáticos

static As propriedades e métodos modificados pertencem à própria classe, e não à instância:

(1) Propriedades e métodos estáticos

TYPESCRIPT
class MathUtils {
  static PI: number = 3.14159;

  static circleArea(radius: number): number {
    return MathUtils.PI * radius ** 2;
  }

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

// No need to create an instance,Call directly using the class name
console.log(MathUtils.PI);              // 3.14159
console.log(MathUtils.circleArea(5));   // 78.53975
console.log(MathUtils.clamp(150, 0, 100));  // 100

(2) Blocos estáticos (TypeScript 5.0 / ES2022+)

TYPESCRIPT
class Config {
  static host: string;
  static port: number;

  // Static Initialization Block
  static {
    Config.host = process.env.HOST ?? "localhost";
    Config.port = Number(process.env.PORT) || 3000;
  }
}

(3) A diferença entre membros estáticos e membros de instância

TYPESCRIPT
class Counter {
  static totalCount: number = 0;   // Shared by all instances
  instanceCount: number = 0;       // Each instance is independent

  increment(): void {
    Counter.totalCount++;
    this.instanceCount++;
  }
}

let c1 = new Counter();
let c2 = new Counter();

c1.increment();
c1.increment();
c2.increment();

console.log(`Examples1:${c1.instanceCount}`);  // 2
console.log(`Examples2:${c2.instanceCount}`);  // 1
console.log(`Total:${Counter.totalCount}`); // 3


▶ Exemplo: Classe com modificadores de acesso e construtor abreviado

Saída:

TEXT 📖 Somente leitura
100C = 212F
0C = 32F
TYPESCRIPT
class Article {
  constructor(
    readonly id: number,
    public title: string,
    private _views: number = 0
  ) {}

  get views(): number {
    return this._views;
  }

  incrementViews(): void {
    this._views++;
  }

  toString(): string {
    return `[${this.id}] ${this.title} (${this.views} views)`;
  }
}

let post = new Article(1, "Hello TypeScript");
post.incrementViews();
post.incrementViews();
console.log(post.toString());  // "[1] Hello TypeScript (2 views)"
// post._views;  // ❌ private — cannot access from outside

Saída:

TEXT 📖 Somente leitura
100C = 212F
0C = 32F

▶ Exemplo: Métodos de fábrica estáticos e propriedades readonly

Saída:

TEXT 📖 Somente leitura
100C = 212F
0C = 32F
TYPESCRIPT
class Point {
  constructor(
    public readonly x: number,
    public readonly y: number
  ) {}

  static origin: Point = new Point(0, 0);

  static fromAngle(angle: number, distance: number): Point {
    return new Point(
      Math.round(distance * Math.cos(angle)),
      Math.round(distance * Math.sin(angle))
    );
  }

  distanceTo(other: Point): number {
    return Math.sqrt((this.x - other.x) ** 2 + (this.y - other.y) ** 2);
  }
}

let p = Point.fromAngle(Math.PI / 4, 10);
console.log(`(${p.x}, ${p.y})`);                // "(7, 7)"
console.log(p.distanceTo(Point.origin));        // "~10"

Saída:

TEXT 📖 Somente leitura
100C = 212F
0C = 32F

❓ Perguntas Frequentes

P: private é realmente privado em tempo de execução? R: Não. O private do TypeScript é apenas uma verificação em tempo de compilação — as propriedades privadas ainda são acessíveis no código JavaScript compilado. A sintaxe #private no ES2022 (campos privados) é o que proporciona verdadeira privacidade em tempo de execução. O TypeScript também suporta #private: class C { #secret = 1; }.

P: Quando se deve usar private e quando se deve usar protected? R: private é usado para detalhes internos de implementação que “somente a própria classe precisa”; protected é usado para membros que “as subclasses também podem precisar acessar ou sobrescrever”. Se você estiver em dúvida, comece com private — você sempre pode alterá-lo para protected mais tarde, se necessário (é mais seguro ser mais permissivo do que mais restritivo).

P: Qual é a diferença entre getters/setters e métodos comuns? R: Os métodos getter/setter fazem com que a leitura e a gravação de propriedades pareçam estar sendo acessadas diretamente (YIJIAN0PH), mas executam uma lógica personalizada nos bastidores. Os métodos comuns exigem chamadas explícitas (YIJIAN1PH). Recomenda-se usar getters/setters para propriedades expostas externamente (para realizar validação ou calcular propriedades) e métodos comuns para implementação interna.

P: É possível usar this em métodos estáticos? R: Em métodos estáticos, usa-se this refers to the classe itself (not an instância). In static create() { return new this(); }, this is equal to the current classe. However, this may be lost in arrow functions or callbacks—it is recommended to use the classe name instead of this.

📖 Resumo

📝 Exercícios

  1. Problema básico (Dificuldade ⭐): Crie uma classe Rectangle (com propriedades de largura e altura) e implemente os métodos getArea() e getPerimeter(). Simplifique o construtor utilizando propriedades parametrizadas.
  2. Problema avançado (Dificuldade ⭐⭐): Crie uma classe BankAccount — torne balance privado, permita operações por meio dos métodos deposit e withdraw, exponha o saldo como somente leitura usando um getter e verifique se o saldo é suficiente antes de uma operação withdraw.
  3. Desafio (Dificuldade: ⭐⭐⭐): Implemente uma classe genérica Stack<T> — armazene dados em um array privado, forneça os métodos push, pop, peek e size, implemente a propriedade size (somente leitura) usando getters e use um método estático static fromArray<T>(items: T[]): Stack<T> para criar uma pilha a partir do array.
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%