Converting a Typescript game to Javascript
The following is an AI generated summary of the video
Why I Finally Moved a Personal JavaScript Project to TypeScript
For over a year, I've been slowly building a JavaScript game as a personal project.
It's one of those projects that never really ends.
Every few months I come back to it, add a feature, refactor something, experiment with an idea, and then put it aside again while life gets busy.
Recently, after returning to the codebase following a long break, I realised it was time for a significant change.
It was finally time to adopt TypeScript. :contentReference[oaicite:0]{index=0}
The Problem With Returning to Old Code
One challenge with long-running personal projects is that you're effectively collaborating with a stranger.
Past-you made decisions.
Present-you has to understand them.
After several months away from the project, I found myself staring at code I'd written and struggling to remember why certain decisions had been made.
The code worked.
Mostly.
But it wasn't as easy to reason about as I'd like.
Future-me deserved better. :contentReference[oaicite:1]{index=1}
The Original Approach
The game was intentionally simple.
No frameworks.
No build system complexity.
No runtime dependencies.
Just plain JavaScript files combined into a single build.
In many ways, it felt like web development from fifteen years ago.
And honestly, I quite liked that.
The simplicity made it easy to debug and experiment with.
I could open the browser console, tweak values on the fly, and immediately see the results.
For rapid experimentation, it was wonderful.
For maintaining a growing codebase, less so. :contentReference[oaicite:2]{index=2}
JavaScript's Biggest Weakness
I've always enjoyed JavaScript.
But JavaScript has one weakness that becomes increasingly painful as projects grow:
It doesn't know what shape your data should be.
Objects can become almost anything.
Properties can appear and disappear.
Functions can receive unexpected inputs.
Many bugs don't reveal themselves until runtime.
That's fine for small scripts.
It's less fine when you're trying to understand a codebase months after you last touched it. :contentReference[oaicite:3]{index=3}
Why TypeScript?
The appeal of TypeScript isn't that it makes bad code good.
The appeal is that it eliminates entire categories of mistakes.
Instead of discovering problems while running the application, many issues are caught during development.
TypeScript provides:
- Static typing.
- Better tooling support.
- Safer refactoring.
- Improved code navigation.
- Clearer contracts between components.
Most importantly, it makes code easier to reason about. :contentReference[oaicite:4]{index=4}
Using AI for the First Pass
One interesting aspect of the migration was using AI to accelerate the initial work.
I asked an AI coding assistant to generate several pull requests that moved parts of the project towards TypeScript.
Some of the suggestions were excellent.
Others weren't.
Ultimately, I accepted some changes, rejected others, and completed most of the migration myself.
The AI wasn't replacing the work.
It was helping me get started. :contentReference[oaicite:5]{index=5}
The Compiler Becomes a Team Member
The biggest benefit appeared almost immediately.
Once TypeScript was integrated, the compiler started highlighting assumptions I'd been making without realising it.
Objects weren't always the shape I thought they were.
Boundary conditions weren't always handled correctly.
Certain pieces of code only worked because of fortunate circumstances.
The migration exposed bugs that had been hiding quietly in the background.
Not catastrophic bugs.
But the sort of subtle issues that eventually become frustrating. :contentReference[oaicite:6]{index=6}
The Unexpected Joy of Constraints
One thing I've learned over the years is that constraints are often helpful.
TypeScript introduces constraints.
You can't just pass any value anywhere.
You can't pretend an object contains fields it doesn't actually have.
The compiler forces you to be explicit.
At first, that can feel restrictive.
Over time, it becomes reassuring.
The codebase starts pushing back when you're about to do something questionable. :contentReference[oaicite:7]{index=7}
The One Thing I Miss
There is one aspect of plain JavaScript I genuinely miss.
Runtime tinkering.
Previously, almost everything lived in the global scope.
I could open the browser console, modify values directly, and immediately experiment with gameplay behaviour.
Adjust a steering value.
Change a rendering distance.
Modify a constant.
Instant feedback.
Moving to a more structured TypeScript setup makes that style of experimentation harder.
Not impossible.
Just less immediate.
And for game development, that kind of rapid experimentation is surprisingly valuable. :contentReference[oaicite:8]{index=8}
Better Tooling, Better Habits
The migration also encouraged me to tighten up the rest of the development process.
The project now includes:
- TypeScript compilation.
- ESLint validation.
- HTML validation.
- Unit tests.
- Development tooling for safer refactoring.
None of these tools are revolutionary on their own.
Together, they create a development environment that catches mistakes earlier and makes future changes less risky. :contentReference[oaicite:9]{index=9}
Learning Through Building
The real reason for doing this wasn't technical.
It was educational.
I wanted to learn TypeScript properly.
Not by watching videos.
Not by reading documentation.
By using it.
There's a difference between understanding a technology intellectually and having it become part of your working vocabulary.
That only happens through practice. :contentReference[oaicite:10]{index=10}
Why Personal Projects Still Matter
One thing I've noticed over the years is that professional coding and hobby coding serve different purposes.
At work, code solves business problems.
In personal projects, code solves curiosity.
The game itself may never be released.
It may never be finished.
That's fine.
The value isn't just the end product.
The value is the learning, experimentation, and enjoyment that happens along the way. :contentReference[oaicite:11]{index=11}
Final Thoughts
Moving this project to TypeScript has already made the codebase easier to understand, safer to modify, and more enjoyable to maintain.
More importantly, it reminded me why I started programming in the first place.
Not for frameworks.
Not for certifications.
Not for career progression.
Because building things is fun.
And sometimes the best way to learn a new technology is simply to pick a project you care about and start refactoring.