microsoft / microsoft/TypeScript

Suggestion: support compile time annotations alongside runtime decorators

Abierto
#30,723 5 comentarios 48 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Awaiting More Feedback Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

Search Terms

annotation
compile time decorator

Suggestion

The way that decorators are currently implemented in TypeScript mirrors their functionality in JS in that they exist at run time and work on run time objects. Because of TypeScript's transpiled nature, a tremendous amount of important metadata is lost by the time decorators are run. Even with the reflect-metadata package, important type information is lost. This represents a nearly insurmountable hurdle in developing high quality software in some extremely important areas.

Consider the case of dependency injection. Any of the TS containers require manually wiring the container together and, even worse, a healthy amount of invocation-site syntactical noise. I come from a Java background, and I think about the Spring DI container, where there is no manual configuration and there is no invocation-site noise, because there's no invocation site. The container is constructed at compile time based on annotations and classpath discovery, which leads to a much smoother developer experience. Building a DI container in TS with that level of developer ergonomics would be a pretty herculean task.

Consider the case of automatically generating webservice code from static model definitions. I'm not even sure if this is currently possible, but it's a feature that developers coming from mature web frameworks expect.

I believe that these two things, as well as a myriad of other cases where AOP is well applied, are important pieces that should be available in the TS ecosystem. TS is a compiled language and constraining the metaprogramming (decorator) facilities to what is available in JS code prevents these tools from being developed, or at least greatly slows their progress.

To this aim, I would like to suggest the addition of compiler annotations: functions that run on compiler nodes at compile time, have the ability to output additional code and otherwise interact with the compiler, but do not have the ability to mutate the compiler nodes. These suggested annotations would only ever be compile-time metadata, whereas decorators are run-time mutators. Adding or removing decorators will change run time behavior, but annotated code should always compile to the same code whether annotations are added or removed. Annotated code may inform a framework that other code is to be generated, but are otherwise completely erased in the JS code and exist only as a compiler facility.

I believe it's fully possible to do all of this now with a custom compiler step that outputs generated code, and it may even be possible to integrate with the language server so that code doesn't have to constantly be generated. I don't believe this violates any of the design goals/non-goals of TS, as the annotations don't change the behavior (or emitted JS) of the annotated code, merely provide an easier facility for library developers to interact with TS and take advantage of the compile step.

I don't want to presume to recommend a syntax or an API to this feature.

To summarize, annotations would:

  • Only exist at compile time and be entirely erased by the compiler
  • Interact with the compiler directly, having access to the compiler node and API
  • Be able to output additional code to be compiled as part of the currently-running compile step
  • Be attachable to (almost?) any node, but have to declare what they can accept (e.g. an annotation for DisableLint would be allowed anywhere, but a Injectable annotation would likely want to narrow its scope)

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

El issue no nombra archivos, pruebas ni puntos de entrada concretos. Empieza revisando la implementación existente de decoradores, las superficies de compiler-node y compiler-API, y la integración con language-server; para darlo por terminado haría falta una sintaxis y una API establecidas para anotaciones en tiempo de compilación que se eliminen del JavaScript emitido y, al mismo tiempo, admitan código generado.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
javascript, typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
20/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.