Hacking the TypeScript Compiler

Extending the language with compiler plugins 🔨

Overview

  • What's the talk about? 🤔
  • Why am I giving this presentation? 👨🏼‍🏫
  • Disclaimer ⚠️

Overview

  • What's the talk about? 🤔
    • Brief summary of some exploratory work I recently did on TypeScript
    • What I learned from that work
    • Demo how to extend TypeScript with compiler plugins
  • Why am I giving this presentation? 👨🏼‍🏫
  • Disclaimer ⚠️

Overview

  • What's the talk about? 🤔
  • Why am I giving this presentation? 👨🏼‍🏫
    • Show the inner working of TS
    • Show that even complex projects are accessible to everyone
    • Encourage "lifting the lid"
    • Encourage open source involvement
  • Disclaimer ⚠️

Overview

  • What's the talk about? 🤔
  • Why am I giving this presentation? 👨🏼‍🏫
  • Disclaimer ⚠️
    • This presentation is quite technical
    • Certain foundational knowledge will be assumed
    • If you don't follow, ask!

Introduction

Why I got involved?

  • Legacy decorators standardised through TC39
  • New decorators don't support design time type reflection
  • DI library I maintain unable to update

Introduction

Why I got involved?

  • Why not!

Working on TSC

The investigation begins 🔎

GitHub issue 57533: Expose design-time type information in TC39 decorator metadata when emitDecoratorMetadata: true
  • Look for relevant GitHub issues
  • Found two competing proposals
  • One was flawed (why?)
  • The other had very little detail or engagement

Working on TSC

The investigation begins 🔎

  • Time to clone the repo!

Working on TSC

The investigation begins 🔎

The getTypeMetadata in the TypeScript codebase

Working on TSC

The investigation begins 🔎

The getTypeMetadata in the TypeScript codebase
  • Looks like this work was planned (15 months ago)
  • How hard can it be?

Working on TSC

Implementing a PoC 👷‍♂️

Modifications to the getTypeMetadata in the TypeScript codebase

Working on TSC

Implementing a PoC 👷‍♂️

🔥
Oops! Everything broke... why?

Working on TSC

Implementing a PoC 👷‍♂️

The metadataHelper in the TypeScript codebase

Working on TSC

Implementing a PoC 👷‍♂️

Modifications to the metadataHelper in the TypeScript codebase

Working on TSC

Implementing a PoC 👷‍♂️

GitHub PR 58101: PROPOSAL Add support for emitDecoratorMetadata for ES decorators
Success! 🥳

Working on TSC

Hitting a road bump 🤕

GitHub issue 57533: Comment: Can you give some examples of how this would work while maintaining this invariant?
In short... no* 😅
* technically class methods and properties are declarations, but classes are "expression declarations".

A fork in the road

(😉)

What are our options?

  • Accept defeat 👎
  • Fork TypeScript 🥵
  • Create a TypeScript compiler plugin 👍

What are compiler plugins?

  • Extensions to TSC
  • Allow modifying diagnostics
  • Allow modifying source code*
  • Allow extending the syntax*
					
						
					
				
* Transformations and syntax extensions require a patched version of TSC (see ts-patch)

Implementing a Plugin

Implementing a Plugin

Step 1: Define the Result

					
						
					
				

Implementing a Plugin

Step 2: Define the Output

					
						
					
				

Implementing a Plugin

Step 3: Implement the Plugin

TypeScript AST Viewer: AST for example input code
TypeScript AST Viewer: AST for example input code
  • Remove label diagnostics
  • Code generation / modification
    • Visitor pattern
    • Node replacement
    • Factory pattern

Implementing a Plugin

Step 3: Implement the Plugin

					
						
					
				

Done! 🥳

A Word of caution ⚠️

  • ts-patch is a third party tool
  • It is only compatible with TSC
  • No SWC, no ESBuild, no type strippers
  • API is relatively stable - but sometime TS internals are needed
  • More for fun/experimentation than for production code

Thank You! ❤️

Further Reading

QR code for the presentation
👆 Scan me to view slides!