boardgame.io
boardgame.io copied to clipboard
Plugin setup ctx issue when using typescript.
I am attempting to use a plugin for the 1st time (having seen a recent reference to the bgio-effects plugin) ... it looks just like something I really want to use.
All was going fine until I got to the point of adding my game to the game server, and then the typescript compiler is throwing an error.
I have reduce this down to a small example:
import { EffectsCtxMixin } from 'bgio-effects';
import { EffectsPlugin } from 'bgio-effects/plugin';
import { Ctx, Game } from 'boardgame.io';
import { Server } from 'boardgame.io/server';
const EffectsConfig = {
effects: {
mediocreCards: {},
},
} as const;
interface GameState {
dummy: number;
}
export const MediocrityGame: Game<
GameState,
Ctx & EffectsCtxMixin<typeof EffectsConfig>
> = {
name: 'Mediocrity',
plugins: [EffectsPlugin(EffectsConfig)],
};
export const server = Server({
games: [MediocrityGame],
});
This causes the following error to be generated on the games: [MediocrityGame],
line:
Type 'Game<GameState, Ctx & EffectsCtxMixin<{ readonly effects: { readonly mediocreCards: {}; }; }>, any>' is not assignable to type 'Game<any, Ctx, any>'.
Types of property 'setup' are incompatible.
Type '((ctx: Ctx & EffectsCtxMixin<{ readonly effects: { readonly mediocreCards: {}; }; }>, setupData?: any) => GameState) | undefined' is not assignable to type '((ctx: Ctx, setupData?: any) => any) | undefined'.
Type '(ctx: Ctx & EffectsCtxMixin<{ readonly effects: { readonly mediocreCards: {}; }; }>, setupData?: any) => GameState' is not assignable to type '(ctx: Ctx, setupData?: any) => any'.
Types of parameters 'ctx' and 'ctx' are incompatible.
Am I doing something wrong?
As I was looking at how plugins worked, I was wondering if the supplied PlayerPlugin
should also provide a PlayerCtxMixin
to allow it to be added to the default Ctx
(otherwise I cannot see how to use the PlayerPlugin when using typescript?
Thanks for this report. I think your usage is correct, but the typings for the Server
function need to be updated to handle customised ctx
types.
A quick workaround may be to use a type assertion when passing the game to the server:
export const server = Server({
games: [MediocrityGame as Game],
});
There aren’t really any drawbacks to asserting there I don’t think, but it would still be good to fix the server typing to handle this automatically.
The PlayerPlugin
does export a type to use like the mixin for bgio-effects
, albeit one that is named very confusingly:
import { Ctx, Game } from 'boardgame.io';
import { PlayerPlugin, PluginPlayer } from 'boardgame.io/plugins';
interface PlayerState {
score: number;
}
const game: Game<G, Ctx & PlayerPlugin<PlayerState>> = {
plugins: [
PluginPlayer<PlayerState>({ /* ... */ })
],
};
Thanks for the workaround.
I actually had to do:
export const server = Server({
games: [MediocrityGame as unknown as Game],
});
because the compiler thinks I might be doing something wrong .
Also thanks for pointing out that the PlayerPlugin does have a equivalent to the Effects Mixin.
I guess a document update with a typescript example for the PlayerPlugin might help others not make the same mistake..
Anyway, great stuff ... now I'm off to work on using the plugins.