smogon / pokemon-showdown

Pokémon battle simulator.
https://pokemonshowdown.com
MIT License
4.79k stars 2.8k forks source link

TypeScript! #3278

Closed Zarel closed 5 years ago

Zarel commented 7 years ago

Been meaning to have an issue about TypeScript. I personally really want some sort of type checking in the repo, also because IntelliSense makes coding a lot nicer on VS Code, but also because PS has had at least a few crashes that could have been caught by stricter type checking.

Supposedly, research says that even in the absence of good test coverage and/or TDD, strict typing rarely leads to fewer bugs. I don't normally like going against research, but either way it still has plenty of benefits.

This issue is mostly to see what other contributors think of TypeScript.

scheibo commented 5 years ago

I then run into problems because I want to make tsc emit code (currently our tsconfig.json has it set not to), but by default it will do it in the same place. However, this causes errors regarding the JS files Originally posted by @scheibo in https://github.com/Zarel/Pokemon-Showdown/issues/3278#issuecomment-466565545

Thought of a workaround for this - we'll have two separate configs:

The emitting configuration will be used by swc/sucrase/tsc or whatever #5199 lands on for ./pokemon-showdown/build runner in package.json.

It's unclear to me why this would be the case. Most of our dependencies are currently globals, anyway (for hotpatch compatibility), so we have some of the affordances that allow us to intermix things in client. Originally posted by @Zarel in https://github.com/Zarel/Pokemon-Showdown/issues/3278#issuecomment-466705089

Yes and no. I dismissed this original, but you're correct that globals will buy use some affordances provided that they are defined (and not just declared) in globals.ts (not server/index.js, which can't require the .ts files to new up the global instances`).


Here we go: https://github.com/pkmn-cc/Pokemon-Showdown/tree/tsc/sim - fully converted. The problem is sim/ is not perfectly encapsulated - some random-team.js files rely on being able to require and call new PRNG, and data/mods/ssb/moves.js uses new Pokemon thanks to something called 'wondertrade'.

I'm going to dive into data/ now...

scheibo commented 5 years ago

Alright: converting all the data/**/random-team.js and data/mods/ssb/moves.js seemed to do it, as npx tsc now compiles without errors. npx mocha on the emitted code fails catatrophically - I think maybe because I tried to change the import pattern from export = ... to export class ... to be more idiomatic in a lot of places. Who knows. Will try again tonight.

Zarel commented 5 years ago

I'd rather spam @ts-ignore in the random team and mods than convert them, tbh.

scheibo commented 5 years ago

Alright, noted. We can evaluate that approach once I get things working. Right now I'm just doing whatever I can to get a working prototype.

scheibo commented 5 years ago

BOOM! We're in business! I've got npm run test working with all tests passing on my branch!‍ :D

Here's what's left:

Follow up after landing:

scheibo commented 5 years ago

From https://github.com/Zarel/Pokemon-Showdown/issues/5199#issuecomment-466859039 I actually think using sucrase renders two of those bullets obsolete because it doesn't give any warnings/errors and is mad fast and probably even simpler to use than tsc plus a special emit.json config. (Y)

scheibo commented 5 years ago

My branch is currently synced to HEAD (there were only 3 small merge conflicts, all related to 3 of my previous commits, doh). I might find time before/after work tomorrow to make ./pokemon-showdown auto build it and then do a pass to polish the changes as I kind of blitzed through this and it definitely needs a sanity check. Still, happy with how it turned out! It was simultaneously a bigger and smaller job that I thought it would be.

Zarel commented 5 years ago

I notice you're using type where the standard is to use interface. e.g. type ChosenAction = { should probably be interface ChosenAction {.

Zarel commented 5 years ago

Sucrase seems fine to me. The only part that would be an issue is initializing properties where they're declared, but I guess we can just avoid doing that.

scheibo commented 5 years ago

Given sim and lib are now native Typescript, and work on server is underway, I don't know that this issue still needs to be open. We are not fully on Typescript yet, but its hard to see us going back now.