1
resposta

Genericos com Typescript

Olá professor, tudo bem? Professor, estou tentando criar uma classe que conterá arrays, como coleções para objetos que defini como interfaces. Na sequência a interface.

export interface Peca {
    nome: string;
    valor: number;
}

Agora a classe que gostaria que fosse a representação de um repositório.

import { Peca } from "../models/peca";

export class Repository {
    private static pecas: Array<Peca> = new Array(); // tentei como Peca[] também
    public static returnRepository<T>(repositorio: string) : Array<T> { // tentei como T[] também.
        if (repositorio.toLowerCase() === 'peca')
            return this.pecas; // Aqui ocorre o erro
    }
}

Erro: O tipo 'Peca[]' não pode ser atribuído ao tipo 'T[]'. O tipo 'Peca' não pode ser atribuído ao tipo 'T'.

O senhor poderia me ajudar nisso?

Pesquisei e encontrei várias soluções, mas praticamente todas assim:

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);
    return arg;
}

Mas eu não quero mandar o array para função, quero que a função retorne a coleção, de acordo ao argumento recebido. Minha ideia é um factory.

Obrigado pela atenção professor

1 resposta

Bom dia Everton. Primeiramente, sua tentativa de aplicar padrões de projetos e a linguagem TypeScript é louvável. Agora vamos aos detalhes.

Talvez seu problema esteja na modelagem, porque eu não entendi o motivo de você ter escrito código dessa forma (inclusive a própria linguagem se recusa a seguir a estratégia que você traçou):

import { Peca } from "../models/peca";

export class Repository {
    private static pecas: Array<Peca> = new Array(); // tentei como Peca[] também
    public static returnRepository<T>(repositorio: string) : Array<T> { // tentei como T[] também.
        if (repositorio.toLowerCase() === 'peca')
            return this.pecas; // Aqui ocorre o erro
    }
}

Se você quer algo genérico, sua classe teria que ser Repository<T>, mas métodos estáticos não tem acesso parâmetro de generics, Uma solução é a seguinte:

export interface Peca {
    nome: string;
    valor: number;
}

export class Repository<T> {
    private pecas = new Array<T>(); // tentei como Peca[] também
    public returnRepository(repositorio: string) : Array<T> { // tentei como T[] também.
        if (repositorio.toLowerCase() === 'peca')
            return this.pecas; // Aqui ocorre o erro
    }
}

const pecas = new Repository<Peca>().returnRepository('peca');

Mas como o código anterior, não vejo sentido nesse nele (talvez eu não tenha entendido o problema que você quer resolver). Aliás, parece que você esta confundindo patterns e tentando aplicá-los impropriamente. Mas se ele resolver algum problema para você, ta aí a solução para resolver.

Pelo o que eu entendo, seu código pode ser escrito simplesmente assim:

export class Repository {
    private static pecas = new Array<Peca>(); // tentei como Peca[] também   
}
const pecas = Repository.pecas; // simples assim

Se eu estiver viajando me fala.

A Alura possui cursos de patterns em várias linguagens, talvez seja interessante dar uma olhada.

Sucesso e bom estudo.