Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

decorator | descriptor function sem retorno?

Oi pessoal, Fiquei com uma dúvida no retorno da função do descriptor:

export function logRuntime (){
    return function (
        target: any, // poder ser um constructor ou propotype da classe
        propertyKey: string,
        descriptor: PropertyDescriptor
    ){

        // guardar o comportamento original no método
        const metodoOriginal = descriptor.value;
        // recebe uma quantidade indefinida de parâmetros to tipo any Array<any>
        descriptor.value = function(...args: any[]){
            // -> "this" vai ser a instância da classe na qual o decorator foi chamado
            // quando associa o método a uma variável, muda o contexto
            const t1 = performance.now()
            // chamar o método original
            // apply permite passar um contexto(this) classe recebida e os parâmetros
            const retorno = metodoOriginal.apply(this, args)
            const t2 = performance.now()
            console.log(`
                ${propertyKey}, tempo de execução ${(t2 - t1)/1000} segundos
            `)
            retorno
        }

        return descriptor;
    }
}

Não entendi o porque em "descriptor.value = function..." não temos um return e sim simplesmente a variável "retorno". Temos isso:

descriptor.value = function(...args: any[]){
            // -> "this" vai ser a instância da classe na qual o decorator foi chamado
            // quando associa o método a uma variável, muda o contexto
            const t1 = performance.now()
            // chamar o método original
            // apply permite passar um contexto(this) classe recebida e os parâmetros
            const retorno = metodoOriginal.apply(this, args)
            const t2 = performance.now()
            console.log(`
                ${propertyKey}, tempo de execução ${(t2 - t1)/1000} segundos
            `)
            retorno
        }

em vez de (última linha):

descriptor.value = function(...args: any[]){
            // -> "this" vai ser a instância da classe na qual o decorator foi chamado
            // quando associa o método a uma variável, muda o contexto
            const t1 = performance.now()
            // chamar o método original
            // apply permite passar um contexto(this) classe recebida e os parâmetros
            const retorno = metodoOriginal.apply(this, args)
            const t2 = performance.now()
            console.log(`
                ${propertyKey}, tempo de execução ${(t2 - t1)/1000} segundos
            `)
            return retorno
        }

O TS já entende que a variável no final já é o retorno da função?

Obrigado,

2 respostas
solução!

Fala Luis, na verdade deveria ter um retorno ai, o professor esqueceu ou simplesmente deixou assim pq o método anotado não tem retorno, é um void. Agora se vc fizer essa mesma anotação num método que tem retorno, ai dá erro!

Não é necessário retorno, como bem explicou o Jhonatan. Outra coisa curiosa é que acho que também não é necessário nem definir essa variável retorno atribuindo a execução do método. Colocando apenas metodoOriginal.apply(this, args) na linha deu certo aqui.