Phaser: Issue with the Phaser.Types.Core.GameConfig TS definitions in 3.17.0

Created on 13 May 2019  路  12Comments  路  Source: photonstorm/phaser

Version

  • Phaser Version: 3.17.0
  • Operating system: not important
  • Browser: not important

Description


My scene's extend from 'Phaser.Scene', but when I updated my project to use 3.17.0 I got the following error in my Phaser.Types.Core.GameConfig object :
Type '(typeof IntroScene)[]' is not assignable to type 'Function | Scene | SettingsConfig | CreateSceneFromObjectConfig | Scene[] | SettingsConfig[] | CreateSceneFromObjectConfig[]'.

Theirs an issue with the type defs for 'Phaser.Types.Core.GameConfig' for scene's that extend from 'Phaser.Scene'.
I had to add the following to the definitions to make my code work again : typeof Phaser.Scene | typeof Phaser.Scene[] |.

馃悰 TypeScript Bug

Most helpful comment

@photonstorm The issue here is that the current type definitions allow you to pass a single Scene _instance_ or an array of Scene _instances_. That's what Phaser.Scene | Phaser.Scene[] is currently indicating. However, if you pass an array of Scene classes or a Scene subclasses, you have to indicate that the type allows the constructor function representing those classes. That's why the scene type should also include Array<typeof Phaser.Scene> or Function[]. Since the scene type already includes Function, the case where someone passes just a single Scene class or subclass currently works.

All 12 comments

Hmm, but that is exactly what's in the type def:

* @property {(Phaser.Scene|Phaser.Scene[]|...

Which means it's the TS Parser that is messing this up.

Yeah I found it also strange that that wasn't enough.

Here a small class example :

export class TestScene extends Phaser.Scene {
  constructor() {
    super({
      key: 'TestScene',
    });
  }
}

Gives this error for an object of type Phaser.Types.Core.GameConfig :

Type '(typeof TestScene)[]' is not assignable to type 'Function | Scene | Scene[] | SettingsConfig | SettingsConfig[] | CreateSceneFromObjectConfig | CreateSceneFromObjectConfig[]'.
  Type '(typeof TestScene)[]' is not assignable to type 'Scene[]'.
    Type 'typeof TestScene' is missing the following properties from type 'Scene': sys, game, anims, cache, and 22 more.

Seems he needs to have all the properties on the class it self.

If you read : https://www.typescriptlang.org/docs/handbook/type-compatibility.html
It's a bit more clear why he gives this error, he tries to see if my class has all the properties of scene.
Just a bit strange that he ignores the extends all together for this. Didn't found a clear answer to that.

@photonstorm The issue here is that the current type definitions allow you to pass a single Scene _instance_ or an array of Scene _instances_. That's what Phaser.Scene | Phaser.Scene[] is currently indicating. However, if you pass an array of Scene classes or a Scene subclasses, you have to indicate that the type allows the constructor function representing those classes. That's why the scene type should also include Array<typeof Phaser.Scene> or Function[]. Since the scene type already includes Function, the case where someone passes just a single Scene class or subclass currently works.

Array<Phaser.Scene> = Phaser.Scene[]
or
Array<typeof Phaser.Scene> = typeof Phaser.Scene[]

Function[] would be almost the same as putting back any like it was before in 3.16 .
I see in the current definition theirs also | Function, Is their code that checks for a function? and calls it in case it is a function? Else it removes a bit the point of adding the definitions.

It just the way typescripts 'type compatibility' check works, and if you place the exact 'class', it expects exactly that class or an object that has exactly the same properties.

I agree that typeof Phaser.Scene would be better than Function if it's the case that only Phaser.Scene types are actually allowed.

The scene seems to get passed to this eventually:
https://github.com/photonstorm/phaser/blob/master/src/scene/SceneManager.js#L643
which seems to imply that any function works, maybe?

Any function works.

Ok茅, that leaves a lot of options open, almost the same as any then 馃槃

This breaks previously working GameConfigs for me too. TypeScript 3.x, upgrading from Phaser 3.16.x to 3.17.

Is there any harm in using instances of MyScene instead of the class itself, like @athasach mentioned, until this issue is resolved?

@cheesepencil To get around this, I used instances of the scene objects (instead of the classes themselves) and it worked.

Using the class symbol worked in the old typings because the scene property was typed as object, which includes arrays of anything. The Function type is a technically correct way to represent a class constructor, but using typeof Phaser.Scene and Array<typeof Phaser.Scne> should be the better option since with Function it will even accept functions that return anything other than valid scene subclasses or scene configs.

Adding function[] back into the list causes the following TS compiler errors:

../../../types/phaser.d.ts(48564,246): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
../../../types/phaser.d.ts(48564,246): error TS8020: JSDoc types can only be used inside documentation comments.

So another means is required.

Ok, have updated the Parser to deal with this and it compiles properly again now.

If you want to use it right away you'll need to npm run tsdev to build the defs yourself. I'll publish a new set once 3.18 is out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JoeBerkley picture JoeBerkley  路  3Comments

Legomite picture Legomite  路  4Comments

JarLowrey picture JarLowrey  路  4Comments

maikthomas picture maikthomas  路  4Comments

sercand picture sercand  路  3Comments