¿Cómo puedo ver cómo TypeScript calcula los tipos?

18

Problema: estoy trabajando en un archivo que tiene muchos tipos condicionales que derivan sus tipos de tipos condicionales previamente definidos y esto se ha vuelto muy complejo y difícil de depurar cómo se deriva un tipo.

Estoy tratando de encontrar una manera de "depurar" o enumerar cómo el compilador de TypeScript está haciendo su determinación sobre un tipo condicional y seleccionando una ruta para derivar el tipo final.

He revisado las opciones del compilador y todavía no he encontrado nada en esa área ...

Una analogía con lo que estoy buscando en este momento es el equivalente del DEBUG=express:*tipo de configuración que uno podría usar si quisiera ver lo que estaba haciendo un servidor express.

Sin embargo, el problema real que estoy tratando de resolver es poder deconstruir y depurar cómo se deriva un tipo en una definición de tipo jerárquica grande y compleja.

Nota importante: no estoy tratando de depurar la ejecución en tiempo de ejecución del proyecto TypeScript. Estoy tratando de depurar cómo los tipos son calculados por el compilador TypeScript.

Chico
fuente
Simplemente use un buen IDE, cree una instancia de su tipo y pase el cursor sobre el valor en el archivo fuente abierto en su editor. ¿Hay alguna información adicional deseada que se pierda al usar esa sugerencia?
Patrick Roberts el
@PatrickRoberts: gracias por la respuesta. Cuando hago eso, apunta a un tipo complejo que tiene tipos condicionales anidados. Eso a su vez apunta a otro tipo complejo similar y continúa y, a veces, se ramificará de una manera que no es obvia. Tratando de averiguar cómo depurar por qué está ocurriendo ese tipo de rama de construcción.
Guy
1
Creo que su pregunta se beneficiaría de un ejemplo concreto para demostrar esto. También me he encontrado con la situación que está describiendo anteriormente, pero generalmente encuentro que la solución consiste en reescribir los tipos de manera que sean más opacos (por ejemplo, un genérico interfacecon un nombre de contenedor autodocumentado en lugar de un genérico typeque intente expandir su definición en la información sobre herramientas del IDE) o simplemente refactorizando la fuente para evitar el uso excesivo de tipos condicionales complejos por completo.
Patrick Roberts el
@PatrickRoberts tratando de actualizar este repositorio a Hapi / Joi @ 16 y depurar la generación de tipos es lo que llevó a esta pregunta. github.com/TCMiranda/joi-extract-type
Guy
@PatrickRoberts este es el problema específico que discute la actualización en sí misma para el contexto. github.com/TCMiranda/joi-extract-type/issues/22
Guy

Respuestas:

1

No hay ningún mecanismo incorporado en mecanografiado para cerrar la información deseada en cuestión. Sin embargo, si está interesado en comprender el trabajo interno, este es el lugar en el código fuente donde ocurre la resolución real de los tipos condicionales.

Echa un vistazo a estos lugares en checker.ts.

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


Adjunto hay un plugin mecanografiado a medio hacer que armé descuidadamente. Se desconecta la estructura de datos en bruto de a ConditionalType. Para entender esta estructura, verifique types.ts ln: 4634.

La experiencia de usuario de este complemento es terrible, pero esa estructura le dice cómo el mecanografiado decide el valor final de un tipo condicional.

Algunas instrucciones molestas y detalladas para ejecutar este complemento:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json y escribe { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. copia y pega este fragmento en index.ts, usa tsc para compilarloindex.js
  5. yarn link
  6. ahora cdal directorio de tu propio proyecto ts, ejecutayarn link my-ts-plugin
  7. agregar { "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }a sutsconfig.json
  8. agregar al espacio de trabajo configurando (.vscode/settings.json)esta línea:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. Abra la paleta de comandos vscode y ejecute:
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. debería poder ver el cierre de sesión del complemento "PLUGIN UP AND RUNNING", ahora abra un archivo de código ts y desplace el mouse hacia algún nodo de tipo condicional, debería ver una estructura de datos json muuuuuuuuuuuu larga agregada al archivo de registro.
hackape
fuente
Gracias por eso @hackape. Lo he estado pirateando y puedo producir algunos registros que son interesantes y enumeran lo que veo de manera interactiva cuando uso VSCode, por lo que no me ha llevado mucho más allá de donde estaba. Buenas instrucciones sobre cómo hacer que ese complemento funcione.
Chico
Te di la recompensa. Aunque no me ha llevado a la solución, creo que con más esfuerzo de mi parte modificando ese complemento, probablemente podría llegar allí y no puedo imaginar que haya una mejor solución para esto en el futuro cercano. ¡Gracias por su ayuda y esfuerzo!
Chico
1
@ Guy Gracias por la recompensa. Así que ayer pasé un par de horas más tratando de obtener resultados más útiles. Tienes razón. La estructura de datos anterior captura el objeto AST-ish de la cadena de tipo condicional, pero es solo el resultado analizado, no el resultado evaluado. En cuanto al "por qué" o qué rama condicional toma el resolutor de tipo cuando evalúa, requiere descartar los resultados de todos los pasos intermedios, algo así como poner una debuggerpausa en algún lugar y luego buscar manualmente los ámbitos locales en las pilas de llamadas.
pirateo el
1
He modificado la getConditionalType()de checker.tshacer un texto mecanografiado de generación personalizada, insertar alguna lógica efecto secundario a volcar información intermedia a lo largo del camino. Y esta vez obtuve algo un poco más útil. Limpiaré mi código y adjuntaré una idea más adelante.
pirateo el
1
@Guy the
gist