Existe uma maneira de definir o tipo de retorno da função para depender do tipo de uma variável local?
Eu tenho um conjunto de métodos de validação:
validateA(things: Thing[]): { badA: string[], badB: number[] }
validateB(things: Thing[]): { anotherBadA: string[], anotherBadB: number[] }
E então eu tenho um wrapper destinado a basicamente executar todos eles e mesclar seus resultados:
validateAllTheThings(things: Thing[]) {
const problems = {
...this.validateA(things),
...this.validateB(things),
};
return problems;
}
Portanto, validateAllTheThings
deve ter o tipo de retorno igual ao tipo de problems
, que são todos os objetos retornados mesclados.
A maneira mais limpa que encontrei para usar ReturnType
:
function validateAllTheThings(things: Thing[]): ReturnType<WrapperClass['validateA']> & ReturnType<WrapperClass['validateB']> {
Mas isso é muito detalhado e não será bem dimensionado. Seria bom se eu pudesse vincular o tipo de retorno da função ao tipo inferido de problems
.
De modo geral, a maioria dos casos de uso para tipos de retorno de assinatura de chamada são atendidos por:
Parece que você está procurando uma maneira de obter parte ou todo o comportamento dinâmico da inferência de tipo e, ao mesmo tempo, anotar explicitamente o tipo de retorno. Não está claro para mim qual caso de uso isso serviria.
Ainda assim, eu diria que se você está procurando uma maneira de dizer "combinar os tipos de retorno dos seguintes métodos via interseção" de uma forma menos complicada, você poderia escrever um tipo de utilitário para fazer isso:
Este tipo apenas os usa
ReturnType
e combina usando uma técnica semelhante à mostrada em Transformar tipo de união em tipo de interseção . E então você pode usá-lo:e você pode verificar se o tipo retornado é equivalente ao tipo desejado:
Finalmente, considerando a questão pelo valor nominal, você poderia simplesmente anotar o tipo de retorno usando
typeof
a variável local:Mas isso só funciona se você não estiver emitindo arquivos de declaração com a
--declaration
opção do compilador . Caso contrário, você receberá o aviso de que o tipo de retorno declarado se refere a um nome inacessível:Então essas são as opções que posso ver. Pessoalmente, prefiro anotar ou permitir inferências e não tentar dividir a diferença, mas pode haver casos de uso em que uma das alternativas seja preferível.
Link do Playground para o código