I don't see any TypeScript definition files, nor an @types/boardgame.io module on npm.
I'm open to adding typescript definition files if you want to send me a PR. I would prefer that the codebase stays in JS for now, though.
@shirakaba if you'd like a starting pointβΒ @Felizardo has a file in his turnato repo:
https://github.com/Felizardo/turnato/blob/master/%40types/boardgame.io/index.d.ts
There was also a little discussion around TS when discussing the Angular client: https://github.com/google/boardgame.io/issues/131
@chrisheninger That's invaluable, thank you!
Would a single-file declaration describing the whole codebase via many declare module "x" {} statements be preferable to declaration files alongside each JS file, then?
For now, I've had to do declaration files alongside each JS file because I'm unsure how else to make test files for the typings. The test files are similarly littering the UI folder. I've also been incrementally adding the types into one global declaration file so that we have both options.
You can see my progress on my fork, on the shirakaba/typescript branch.
I've so far typed all the src in the UI folder, but still have a few issues to resolve...
The foremost issue is that I don't know how to correctly type Logo and Card (which both use stateless component functions β what's more, they're assigned to const variables, and Logo adds in a default export to increase the headache further). Some help there would be appreciated.
Generally, I'm surprised that the UI components have so many optional features, and that many of them expect just a single child rather than multiple children.
In the ui/token.js, defaultProps.template references the Square class but doesn't construct an instance of it; is this a bug?
What templates may Token accept? Just Squares?
There's plenty more work to be done, still. Would welcome any extra pairs of hands.
The foremost issue is that I don't know how to correctly type Logo and Card (which both use stateless component functions
I figured it out with a little reference to https://github.com/piotrwitek/react-redux-typescript-guide#component-typing-patterns and some guesswork.
I now have Logo and Card typings that permit all the patterns used in logo.test.js and card.test.js, but I've stumbled across a question for more experienced React developers:
Should each of these UI elements accept all props specified for their element type, e.g.: HTMLAttributes<HTMLDivElement>? Or should consumers of the library be restricted to inputting only the props specified in propTypes? I guess they should accept all relevant HTML attributes, to be in line with is permitted through use of the (untyped) JSX..?
Typings for server folder provided now. Some left as any as I need to type the core before I can get more specific with some values.
@shirakaba Is the intent that these typings ship with boardgame.io instead of in DefinitelyTyped? I see that they're in the repo now in your fork, but wasn't sure if that was a temporary thing as you worked on the typings.
@scally I'd ideally prefer to ship them with boardgame.io directly, so that maintainers can keep the JS typings definitely in step for each given version of the repo. Otherwise, it becomes unclear which version of the typings one would need to install to match, say, v1.2.3 of the repository (a common headache for TS devs).
More than anything though, I'm not sure how to concatenate individual typings into a single file; there are a few things like default exports and modules that I don't know how to handle in the form of a single-file declaration β which would also impede me from launching it as a DefinitelyTyped project.
I'm not sure what the linting settings for DefinitelyTyped are, either β likely I'd have to rewrite a bunch of stuff.
Still open for discussion about how best to organise the files (ideally, they should only end up being seen in dist, but yes, I'm just writing them in the src folder for now before thinking about the final repo structure).
I've just finished making typings for the core module (with a small number of TODO notes here and there for review) β whew!
I've now written typings for all the JS in src (having just finished typing the client module). π
On reflection, I've just noticed that I could write typings for the four CSS files, too π€ could try, I guess.
Blockers:
I'll need to do another pass to add the (fairly insubstantial) typings tests for core and client, but the hard part is done now, at least.
I should try applying the typings to some/all of the example projects to see if anything comes up.
We need to discuss the structure for where to put all these files. I'm happiest just leaving the .d.ts files directly alongside their .js counterparts, because it makes the development experience much better (you don't need to wade through thousands of lines to find the typings you need), and keeps the modularity intact. The other option is to concatenate the typings into one mammoth file, but I'm not actually sure how to do that.
I'll need to sign the Google contributors agreement before making any pull request; will need to speak with my company about this first.
The pull request will need review particularly by contributors who really understand how React and Redux should be typed (I'm sure the Redux typings won't be perfect).
Another option that would eliminate most of the blockers would be to keep it in a separate repo for now until we reach v1.0 and have a stable API (and merge it in then). I worry that the lack of TypeScript expertise and the ever changing API during the alpha stage would make development inconvenient for developers in this repo.
@nicolodavis Sorry for the late reply.
keep it in a separate repo for now until we reach v1.0
Is there a timescale in mind for this? Naturally I worry about my types drifting out of sync and become obsolete if there's too much change to catch up with, but I'll do my best if TypeScript integration is a real goal.
For now, I'm happy to fill up a separate repo with TypeScript examples and refining the types.
It's looking like the path of least resistance may end up being creating a single-file global declaration after all (as the JS is packaged rather than left as individual source files), so we may even have the option of going through DefinitelyTyped in early stages before merging in post-alpha, although that's rather unattractive for me (the typing and linting strictness is of insanely high standard for DefinitelyTyped, and I have dozens of files to get in line).
I worry that the lack of TypeScript expertise and the ever changing API during the alpha stage would make development inconvenient for developers in this repo.
I'll admit I can see refactoring the JS becoming harder if types need to be kept in step each time.
Thanks @shirakaba!
Yeah, I do think this will be the easiest way to make progress going forward until we hit v1.0 (I'll probably upload a roadmap for this so people have a general sense of the timeline). In the meantime, once you're satisfied with your typings, let me know so I can link to your repo from the documentation here.
I've now combined all the individual-file declarations into one whole-repo index.d.ts modules declaration file (same structure as your original):
https://github.com/shirakaba/boardgame.io/tree/shirakaba/typescript-examples
yarn add https://github.com/shirakaba/boardgame.io.git#shirakaba/typescript-examples
However, I'm getting the classic packaging cache problem: https://github.com/facebook/react-native/issues/4968 and so can't check whether the typings actually work when distributed as one single file.
@Felizardo Did you experience any similar problems when setting up the TicTacToe example? Does your example still compile if you swap your index.d.ts file for mine? Instead of the declared paths being boardgame.io/core, should they include the dist folder, i.e.: boardgame.io/dist/core?
Edit: I've tried making a whole new project, separate from the repo, but that's facing the same error, too :( I'm blocked now.
@shirakaba Just in case the DefinitelyTyped option could save you some hassle, I researched some of the pain points you mentioned.
Otherwise, it becomes unclear which version of the typings one would need to install to match, say, v1.2.3 of the repository (a common headache for TS devs).
Some type definitions include a version at the top indicating which release it matches, like this:
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L1
I'm not sure what the linting settings for DefinitelyTyped are, either β likely I'd have to rewrite a bunch of stuff.
It looks like it might be defined per-package like this:
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/tslint.json
Also, tslint (at least its extension in VSCode) can autofix a lot of problems without complaint on save.
Just out of curiousity @nicolodavis is there a particular thing keeping you from wanting to use Typescript for this project? It seems like it might be the path of least resistance to integrating types here.
One thing to add/clarify: I can't get a single-file index.d.ts to work with the bundled js (so DefinitelyTyped is out of the question unless someone can figure it out to unblock me), but the typings would work just fine if the project were to distribute its individual .js files and distribute the respective .d.ts files alongside those.
Thus, DefinitelyTyped could be considered if the js source were to be distributed as individual files rather than bundles.
For me, it's just a lack of knowledge of Typescript that wants me to keep it separate for now. That and the fact that I think the somewhat fluid API at the moment will be harder to modify with more things to keep in sync. I'm totally open to getting it in after we reach v1.0.
Which is also a reminder for me to get started on documenting the roadmap to v1.0.
EDIT: Roadmap link
@nicolodavis Thanks for that roadmap just now.
Oh, I am also maintaining my own .d.ts for my project, lets see if we can collaborate for a single .d.ts :)
@flamecoals My declarations were written a year ago, and I didn't maintain them further, so I'd recommend you just continue with your own. There were some issues with my typings in any case:
I personally think that the way forward is to migrate the codebase to TS (this would only take a weekend) and distribute it as a library of modules, leaving the bundling to the consumer (there is no way to auto-generate declarations for a bundle of TS modules). However, Nicolo is only open to a migration upon reaching a stable version. And I will admit that TS is a double-edged sword when it comes to Redux-based projects; the Intellisense is great, but the typings can be hard to set up.
I see that there's a Gitter. I'll hang out there and get re-acquainted with this project :)
Thanks. I will do my best to make this reusable by others, even if we need to change over time. I will see if there is any way to add automated tests to see if the types broke.
I agree with you that ideally we would use TS everywhere, and I think that having clear interfaces would make my life easier whenever I wanted to contribute to bg.io. I struggle a lot to understand the interfaces right now.
But again, Nicolo did most of the work in this framework so I respect his decisions.
I'm more open to TypeScript these days having gained a bit more familiarity with it.
I'm not opposed to converting some of the code in src/core to TypeScript and adopting a gradual typing approach to converting the project over. My main concern is that it might reduce the pool of potential contributors.
If either of you has some time, I'm happy to look at a PR that adds some types to src/core/flow.js and src/core/reducer.js. These are the two places that will benefit the most from having types.
I'm more open to TypeScript these days having gained a bit more familiarity with it.
Oh, cool :)
My main concern is that it might reduce the pool of potential contributors.
@nicolodavis This is a valid concern, although the other side of the coin is that it may attract TypeScript devs (and there are quite a lot of us in the React Native community). I've always held back from contributing because I feel a bit powerless to help if typings aren't in place to make clear all the contracts. I'd much rather the IDE enforce my typings than have to hope that the documentation is up-to-date and sufficient.
adopting a gradual typing approach to converting the project over
Incremental adoption is certainly possible, but presents some problems:
Incremental adoption does make sense in terms of reviewing PRs and reducing merge conflicts from active PRs.
I'd love to try, if we can clarify the issues of bundling and shipping.
Right now Rollup generates a few different files for various subpackages (one for each file in the package directory).
Regardless of whether we convert some (or all) the code to TS, we'll still need to generate these JS files in the final NPM as well as a minified bundle that users can insert via a <script> tag.
I'm thinking that we can just convert all the code that corresponds to one subpackage to TS as a pilot and see how it goes. core.js is a good candidate for initial conversion. This will just benefit repo contributors initially (i.e. no need to maintain a declarations file for now) and the idea is that we'll eventually convert everything over so that it can be consumed as a TS library.
Do the TS sources go into a separate NPM package? We'd still need to keep the current NPM with the JS code as-is so that JS users can consume them.
Are you saying that we don't need a declarations file if everything is in TS? I'm assuming that we'd still need to export the same types that correspond to the external interfaces of the library.
Regardless of whether we convert some (or all) the code to TS, we'll still need to generate these JS files in the final NPM as well as a minified bundle that users can insert via a
@shirakaba How are you faring with the TypeScript port? I will likely be touching code in flow.js soon, so just wanted to check if you're almost done and I should just wait instead.
@nicolodavis Unfortunately, it's been a tough month β life got in the way and I'm nowhere on it. Feel absolutely free to tinker with flow.js.
Just wanted to chime in as a random developer interested in getting into TypeScript and boardgame.io, that I am super interested in this thread and looking forward to seeing how it unfolds. Thanks for all the work so far, it made for some interesting reading!
Hi,
I tried to re-write the Tic-Tac-Toe tutorial scripts using TypeScript, and in the process I also wrote index.d.ts file based on an existing example .
https://gist.github.com/qsona/e570cc23179640f00601a7995bc3336e
There is much room to improve them (still so many any types). This is just WIP work.
I'm currently working on a "playing card game" project in Typescript
So I made a quite generic boardgame.io.d.ts too (though I've only typed what I use in my project, so most of core and react at this point).
I made it in a way that boardgame.io can hold our own game types (by giving him some type arguments).
Example usage for boardgame.io/core in my Game config:

Example usage for boardgame.io/react in my board component:

My priority is to finish my project, but if boargame.io still doesn't have any .d.ts files when I'll finish it, I may take some time to submit a PR.
UPDATE: Actually, the file is growing with my project, it would be a waste of time to submit it before it's mature
thanks @jasonharrison
it seems that the PR you're linking only allowed the boardgame.io to host TS files
in term of typings, it won't help much with our TS projects yet
hopefully types are going to pop faster now that you've started the TS integration, good job π
@Oliboy50 Yup, my PR was so BGIO can begin to use TypeScript :)
I actually am not sure how to tell NPM about our declaration files (blah.d.ts)...
I am getting confused about how to get our declaration files recognized by NPM because we use Rollup and aliases and such.
If you're familiar and you have the time, maybe you could help me with this?
This is more or less done now. The only thing that remains is to export (tsc generated) type definitions in the NPM and then users will have types for the external interfaces of boardgame.io.
@nicolodavis looking forward to it!
This is available now β if not documented yet.
General types can be imported directly from boardgame.io, for example:
import type { Game } from 'boardgame.io';
interface G {
score?: number;
deck: string[];
}
const game: Game<G> = {
name: 'my-game',
// setupβs return will be checked against your G type
setup: () => ({
deck: [],
}),
}
How exactly are types being added?
This is what GameConfig.setup is typed as here
setup?: (ctx: Ctx, setupData?: any) => any;
but in dist/types/src/types.d.ts it shows up as simply
setup?: Function;
Which is not nearly as helpful
@crhistianramirez Which version are you using? This was fixed in 866e8978ca65f969c8343baa1b99f9ea9b63a1ce and released in v0.39.4.
@delucis that is the version I have downloaded.
I downloaded zip of the release and inspected the contents. Not seeing it there yet. Thinking it might not have been built before it was published
Ah, that ZIP is just the source code, not the built release, but taking a look, the release does seem to be missing this update, so maybe your hunch is correct:
https://unpkg.com/browse/[email protected]/dist/types/src/types.d.ts
@nicolodavis Is it possible Typescript did an incremental build when you released and didnβt include these updates or that the TS command isnβt auto-run on release?
The TS command is run by Rollup, so I'm not sure what's broken here. Let me push another release and see if that resolves it.
@crhistianramirez Can you try 0.39.5?
Looks good, Nicolo!
https://unpkg.com/browse/[email protected]/dist/types/src/types.d.ts
Also, do you guys think that Game would be a more intuitive name than GameConfig?
Perhaps? Itβs actually the same interface as that returned by the Game function right?
Looks good!!
Yes, I agree Game is more intuitive.
The new typescript types in 0.39.6 seem to work really well for me... π―!
I am having some issues with Server types. Various combinations of importing the server object failed to get typings, and only require as per the docs seemed to work (although the import was typed as any). I see these were discussed a bit in #576, so maybe these haven't been implemented yet?
@will-hart Yes, the server module is bundled slightly different from the others as you saw discussed in #576, so its types arenβt exposed correctly when doing import { Server } from 'boardgame.io/server', and that hasnβt been fixed yet. The types are included in the build, (e.g. at boardgame.io/dist/types/src/server/index.d.ts), so Iβll see if I can figure out a quick fix.
@will-hart This should be fixed once #622 is merged and released.
I can't import boardgame.io/client:
ERROR in <xxx>/node_modules/boardgame.io/dist/types/packages/client.d.ts(1,24):
1:24 Cannot find module '../src/client/client'.
> 1 | import { Client } from '../src/client/client';
| ^
2 | export { Client };
3 |
It seems dist/types/src/client is missing:

@coyotte508 I think this is because the client source code hasnβt been converted to Typescript yet. Iβm working on some changes to those files at the moment, so Iβll try to make that conversion while I do.
Ok :)
In the meantime import boardgame.io/dist/cjs/client seems to work
https://github.com/nicolodavis/boardgame.io/pull/622 is released in 0.39.8.
I was running into some issues using the PluginPlayer plugin in 0.43.3 while using TypeScript. Specifically, when trying to create my strictly-typed game definition, I was unable to publicly import the derived PlayerPlugin type to extend Ctx.
Specifically, I tried to define my game like this:
export const GameDefinition: Game<GameState, Ctx & PlayerPlugin<PlayerState>, CustomSetupData> = {
// game definition elided
}
This definition causes my CtxWithPlugins type to properly include the player property with the PlayerAPI<PlayerState> type, which in turn makes my custom PlayerState properties pass type checking when using ctx.player.get and ctx.player.set.
However, the PlayerPlugin type is not a public export of boardgame.io/plugins. In order to gain access to PlayerPlugin I had to use the following import:
import { PlayerPlugin } from 'boardgame.io/dist/types/src/plugins/plugin-player';
Have I made an error, or is this something that can be fixed?
IMO it would make more sense to include PlayerPlugin and other such interfaces in the boardgame.io/plugins package. If this should be fixed, I'd definitely be open to creating a PR if that would be helpful.
Most helpful comment
This is more or less done now. The only thing that remains is to export (tsc generated) type definitions in the NPM and then users will have types for the external interfaces of boardgame.io.