Three percent of JavaScript developers still use libraries with known security vulnerabilities. That’s a stat that should make anyone building anything publicly accessible sweat a little. It’s a constant battle out there, and understanding the fundamentals means you’re less likely to accidentally ship something fragile.
Which brings us to this rather quaint little exercise: building a Rock-Paper-Scissors CLI game in TypeScript. Now, before you dismiss this as child’s play, remember the first rule of coding: the simple stuff often hides the most insidious bugs if you don’t lay down a solid foundation. And that’s precisely what this project, penned by a self-proclaimed Java engineer taking their second stab at TypeScript, aims to do.
Why Bother With a CLI Game?
Look, we’re not talking about the next big crypto exchange here. This is a command-line interface, a bit of digital Tic-Tac-Toe for programmers. But the author’s intent is clear: to get a grip on core TypeScript features like union types and conditional logic, all while wrestling with a testing framework – this time, Jest, after a previous encounter with Vitest. It’s a learning journey, and the messy bits are often the most illuminating.
And honestly, who’s actually making money here? Not the author, certainly. They’re spending their own time, their own cash (on Claude Pro and Cursor Pro, no less) to figure this stuff out. This is pure, unadulterated learning for the sake of understanding. That’s the kind of raw effort we appreciate here at Open Source Beat.
The Code, In Brief
The project is structured neatly, a good sign. We’ve got files for the entry point (index.ts), game logic (game.ts), type definitions (types.ts), and the obligatory tests (game.test.ts). It’s a clean separation of concerns, which, if you’ve been around the block more than a decade, you know is the bedrock of maintainable code.
At the heart of it are these type definitions:
export type Hand = 'rock' | 'paper' | 'scissors';
export type Result = 'win' | 'lose' | 'draw';
Union types. Why not an enum? The author points out that union types offer cleaner logs, which is a fair point when you’re debugging. String literals just read better than a cryptic 0, 1, or 2. And they’ve correctly exported them, understanding that these types will be needed elsewhere. Good.
The Logic: Where Things Get Interesting (or Not)
The determineResult function is where the core game logic lives. It’s a classic scenario for conditional branching.
```typescript export function determineResult(player: Hand