Como posso ver como o TypeScript calcula os tipos?

18

Problema: estou trabalhando em um arquivo que possui muitos tipos condicionais que derivam seus tipos de tipos condicionais definidos anteriormente e isso se tornou muito complexo e difícil de depurar como um tipo está sendo derivado.

Estou tentando encontrar uma maneira de "depurar" ou listar como o compilador TypeScript está determinando um tipo condicional e escolhendo um caminho para derivar o tipo final.

Examinei as opções do compilador e ainda não encontrei nada nessa área ...

Uma analogia com o que estou procurando agora é o equivalente ao DEBUG=express:*tipo de configuração que se pode usar se você quiser ver o que um servidor expresso está fazendo.

No entanto, o problema real que estou tentando resolver é ser capaz de desconstruir e depurar como um tipo é derivado em uma definição de tipo hierárquica complexa e grande.

Nota importante: Não estou tentando depurar a execução em tempo de execução do projeto TypeScript. Estou tentando depurar como os tipos são calculados pelo compilador TypeScript.

Cara
fonte
Basta usar um bom IDE, instanciar seu tipo e passar o mouse sobre o valor no arquivo de origem aberto no seu editor. Há alguma informação adicional desejada que você perca ao usar essa sugestão?
Patrick Roberts
@PatrickRoberts - obrigado pela resposta. Quando faço isso, ele aponta para um tipo complexo que aninhou tipos condicionais. Isso, por sua vez, aponta para outro tipo complexo semelhante e continua, e algumas vezes se ramifica de uma maneira que não é óbvia. Tentando descobrir como depurar por que esse tipo de ramo de construção está acontecendo.
Guy
11
Acho que sua pergunta se beneficiaria de um exemplo concreto para demonstrar isso. Eu também encontrei a situação que você está descrevendo antes, mas geralmente acho que a solução alternativa envolve reescrever os tipos para que sejam mais opacos (por exemplo, um genérico interfacecom um nome de contêiner auto-documentável em vez de um genérico typeque tenta expandir sua definição na dica de ferramenta do IDE) ou apenas refatorar a fonte para evitar o uso excessivo de tipos condicionais complexos.
Patrick Roberts
@PatrickRoberts tentando atualizar este repositório para Hapi / Joi @ 16 e depurar a geração de tipos é o que levou a essa pergunta. github.com/TCMiranda/joi-extract-type
Guy
@PatrickRoberts, esse é o problema específico que discute a atualização por contexto. github.com/TCMiranda/joi-extract-type/issues/22
Guy

Respostas:

1

Não há nenhum mecanismo interno no texto datilografado para desconectar as informações desejadas em questão. No entanto, se você estiver interessado em entender o trabalho interno, aqui está o código-fonte onde a resolução real dos tipos condicionais acontece.

Dê uma olhada nesses lugares em checker.ts.

ln: 13258 instantiateTypeWorker()
ln: 12303 getConditionalType()
ln: 12385 getTypeFromConditionalTypeNode()
ln: 12772getTypeFromTypeNode()


Em anexo está um plug-in datilografado pela metade que montei descuidadamente. Ele efetua logout da estrutura de dados brutos de a ConditionalType. Para entender essa estrutura, verifique types.ts ln: 4634.

O UX deste plugin é terrível, mas essa estrutura diz como o texto datilografado decide o valor final de um tipo condicional.

Algumas instruções irritantemente detalhadas para executar este plugin:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json e escreva { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. copie e cole esse trecho para index.ts, use tsc para compilá-lo paraindex.js
  5. yarn link
  6. agora cdno diretório do seu próprio projeto ts, executeyarn link my-ts-plugin
  7. adicione { "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }ao seutsconfig.json
  8. adicione ao espaço de trabalho definindo (.vscode/settings.json)esta linha:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. abra a paleta de comandos vscode e execute:
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. você poderá ver o logout do plug-in "PLUGIN UP AND RUNNING", agora abra um arquivo de código ts e passe o mouse para algum nó do tipo condicional; você verá uma estrutura de dados json muito mais adicionada ao arquivo de log.
hackape
fonte
Obrigado por isso @hackape. Eu tenho trabalhado com ele e posso produzir alguns logs que são interessantes e listam praticamente o que estou vendo interativamente ao usar o VSCode, para que ele não tenha me levado muito além do que estava. Boas instruções sobre como obter esse plugin funcionando.
Guy
Eu dei a recompensa para você. Mesmo que não tenha me levado à solução, acho que, com mais esforço da minha parte, modificando esse plug-in, eu provavelmente poderia chegar lá e não consigo imaginar que haja uma solução melhor para isso no futuro próximo. Obrigado por sua ajuda e esforço!
Guy
11
@ Buy Obrigado pela recompensa. Por isso, passei mais algumas horas ontem tentando obter resultados mais úteis. Você está certo. A estrutura de dados acima captura o objeto AST-ish da cadeia de tipos condicionais, mas é apenas o resultado analisado, não o resultado avaliado. Quanto ao "porquê" ou qual ramificação condicional o resolvedor de tipos leva ao avaliar, é necessário despejar os resultados de todas as etapas intermediárias, como colocar uma debuggerpausa em algum lugar e depois procurar manualmente os escopos locais nas pilhas de chamadas.
hackape
11
Modifiquei o getConditionalType()in checker.tspara criar um texto datilografado de compilação personalizado, inserindo alguma lógica de efeito colateral para despejar informações intermediárias ao longo do caminho. E desta vez consegui algo um pouco mais útil. Vou limpar meu código e anexar uma essência mais tarde.
hackape
11
@Guy a essência é aqui
hackape