phaser
phaser copied to clipboard
[3.50] Spine, TypeScript & types
With the new Version of Phaser 3.50 my spine integration in TypeScript did not work any more.
Not sure if it is the best way, but it worked for me in Phaser 3.24.1
-
Add own typeRoots to the tsconfig.json
"typeRoots": [ "@types", "./node_module/phaser/types" ]
-
Build an index.d.ts in folder @types\phaser with the following content:
/// <reference path="../../node_modules/phaser/types/SpineGameObject.d.ts" />
/// <reference path="../../node_modules/phaser/types/SpinePlugin.d.ts" />
A request: Could you please write a short tutorial / best practice, how to use spine plugin in a typescript environment?
The errors in my build apparently originate to wrong types in Phaser 3.50. If i open node-modules/phaser/types in Visual Studio Code directly i get the following errors:
-
SpineContainer.d.ts
-
SpineGameObject.d.ts
It seems, that the d.ts files are outdated since the 3.50 Spine Plugin Release
@photonstorm Is there any news, apparently the bug exists also in the latest version 3.52.0
I am using Phaser version 3.52.0
. Just import the SpinePlugin and its types.
import 'phaser/plugins/spine/dist/SpinePlugin';
import 'phaser/types/SpineContainer';
const game = new Game({
plugins: {
scene: [
{
key: SpinePlugin.name,
plugin: SpinePlugin,
mapping: 'spine'
}
]
}
})
If not work, maybe you could take a look at this repo https://github.com/ourcade/phaser3-typescript-spine
First of all thanks for the hint. Unfortunately, this does not work for me. After compiling with tsc there are about 24 errors in my project that some interfaces are implemented incorrectly.
Property 'moveTo' in type 'SpineContainer' is not assignable to the same property in base type 'Container'. Property 'remove' in type 'SpineContainer' is not assignable to the same property in base type 'Container'. Class 'SpineGameObject' incorrectly implements interface 'Transform'. 'addToCache', which lacks return-type annotation, implicitly has an 'any' return type.
The example in the repository is based on Phaser 3.22 this ran exactly the same for me without errors.
I suspect that in the big update to 3.5 something has changed fundamentally and that the *.d.ts are not up to date. If it is your repository, could you may try to update it? Did you do something special in the Typescript configuration?
My tsconfig.json
and i am using typescript 4.2.2
and Wepack5.
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"noImplicitAny": false,
"esModuleInterop": true,
"allowUnreachableCode": false,
"sourceMap": true,
"strictPropertyInitialization": false,
"allowJs": false,
"lib": ["dom", "es5", "esnext"],
"jsx": "react",
"skipLibCheck": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"baseUrl": "./",
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "public/lib/*.js", "dist", "webpack"]
}
You could take a look at my repo. It is base on yandeu/phaser-project-template
src/scripts/game.ts
import 'phaser/plugins/spine/dist/SpinePlugin'
// ...
import spine typing in a standalone typings/spine-plugins.d.ts
( I am not well understanding typescript, but it works... )
import 'phaser/types/SpineContainer'
// you could also extends SpinePlugin if necessary
declare global {
interface SpinePlugin {
bootWebGL(): void;
gameDestroy(): void;
spineFileCallback(this: Phaser.Loader.LoaderPlugin): void;
}
}
I poked through Pong420's the files a bit (thanks for the example code!) and I suspect the "skipLibCheck": true,
in the tsconfig.json
is what's preventing these errors from showing up. According to the documentation, it disables type checking for the *.d.ts
files.
From what I remember of seeing this issue a little while ago the core problem is that SpineContainer
extends Container
imperfectly; as per the docs SpineContainer
should only contain SpineGameObject
objects (where as a generic Container
can contain any GameObject
). TypeScript considers this a violation of the Liskov Substitution Principal since someone could grab a Container
(that's actually a SpineContainer
) and assume they can add GameObject
s to it. I don't see a simple way to rework things to avoid this typing issue, though I'm not a TypeScript authority by any means.
"skipLibCheck": true
seems to do the magic for now.
Thank you guys for the help. I'll see how my common-game-elements work in my new game in the next weeks.
I use phaser v3.55 with angular 12, it's still exist, although use "skipLibCheck": true
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2017",
"module": "es2020",
"lib": [
"es2018",
"dom",
"scripthost"
],
"skipLibCheck": true
},
"typeRoots": [
"@types",
"node_modules/@types",
"node_module/phaser/types"
],
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
},
}