Sobes.tech
Middle

Com o que podem ser substituídos os interfaces em JavaScript?

sobes.tech IA

Resposta da IA

As interfaces em JavaScript não são suportadas nativamente, mas podem ser substituídas por:

  • Verificação de tipos em tempo de execução (Runtime type checking): Uso de bibliotecas como Zod, Yup ou Joi para descrever a estrutura de dados e validar os valores de entrada.

    // Exemplo com Zod
    import { z } from 'zod';
    
    const UserSchema = z.object({
      id: z.number(),
      name: z.string(),
      email: z.string().email(),
    });
    
    try {
      const validUserData = UserSchema.parse({ id: 1, name: 'Alice', email: 'alice@example.com' });
      console.log('Dados do utilizador válidos:', validUserData);
    } catch (error) {
      console.error('Erro de validação:', error.errors);
    }
    
  • JSDoc: Comentários com anotações de tipos para documentação e fornecimento de informações para IDEs e analisadores estáticos.

    /**
     * @typedef {Object} Product
     * @property {number} id - Identificador único do produto.
     * @property {string} name - Nome do produto.
     * @property {number} price - Preço do produto.
     */
    
    /**
     * Mostra informações sobre o produto.
     * @param {Product} product - Objeto do produto.
     */
    function displayProduct(product) {
      console.log(`Produto: ${product.name}, Preço: ${product.price}`);
    }
    
    const myProduct = { id: 101, name: 'Livro', price: 500 };
    displayProduct(myProduct);
    
  • Convenções de nomenclatura e documentação: Acordos claros sobre como os nomes das propriedades e métodos dos objetos descritos na documentação do código devem ser feitos.

  • TypeScript: O método mais eficaz, permitindo usar interfaces completas e tipagem estática durante o desenvolvimento.

    interface IProduct {
      id: number;
      name: string;
      price: number;
      displayInfo(): void; // Definição do método
    }
    
    class Book implements IProduct {
      id: number;
      name: string;
      price: number;
    
      constructor(id: number, name: string, price: number) {
        this.id = id;
        this.name = name;
        this.price = price;
      }
    
      displayInfo(): void {
        console.log(`Produto: ${this.name}, Preço: ${this.price}`);
      }
    }
    
    const myBook: IProduct = new Book(102, 'Romance', 700);
    myBook.displayInfo();
    
  • Classes abstratas (em certa medida): Embora o JavaScript não tenha classes abstratas reais, elas podem ser emuladas gerando erros ao tentar criar uma instância de uma classe abstrata ou chamar métodos "abstratos".

    class AbstractShape {
      constructor() {
        if (new.target === AbstractShape) {
          throw new Error("Não é possível criar uma instância da classe abstrata AbstractShape");
        }
      }
    
      area() {
        throw new Error("O método area deve ser implementado na subclasse");
      }
    }
    
    class Circle extends AbstractShape {
      radius: number;
    
      constructor(radius: number) {
        super();
        this.radius = radius;
      }
    
      area(): number { // Implementação do método abstrato
        return Math.PI * this.radius * this.radius;
      }
    }
    
    // const shape = new AbstractShape(); // Gera erro
    const circle = new Circle(5);
    console.log("Área do círculo:", circle.area());
    

É importante entender que esses métodos oferecem diferentes níveis de rigor e verificação. O TypeScript fornece a verificação estática mais forte durante a compilação, enquanto os outros métodos são mais orientados para a verificação em tempo de execução ou documentação.