Closed DerZyklop closed 6 months ago
Update: My improved workaround…
Instead of staticGroup()
’s Phaser.Physics.Arcade.StaticGroup
, i use my own AcardeStaticGroup
. In the definition, I overwrite the children's type:
export type AcardeStaticGroup = Omit<Phaser.Physics.Arcade.StaticGroup, 'getChildren' | 'children'> & {
children : Phaser.Structs.Set<Phaser.Physics.Arcade.Sprite>;
getChildren() : Phaser.Physics.Arcade.Sprite[];
}
Then i can use it like this:
const someBalls = this.physics.add.staticGroup() as AcardeStaticGroup;
someBalls.create(100, 200, "gems", Phaser.Math.Between(0, 4));
const firstBall = someBalls.getChildren()[0];
firstBall.setCircle(20);
But there would be more work to do if I follow this approach.
I just found another flaw in the same class. Group
has .create(…)
which returns any
. In fact it returns the exact same thing that .children
is an set of.
.children
currently has the type
children: Phaser.Structs.Set<Phaser.GameObjects.GameObject>;
Thus .create(…)
should probably return Phaser.GameObjects.GameObject
.
Or better following my abstract proposal from above:
If .children
is
children: Phaser.Structs.Set<ChildrenType>;
then .create(…)
returns ChildrenType
.
I see two possible solutions here:
class Group<ChildType extends Phaser.GameObjects.GameObject> …
So that every code that uses the type Group
is forced to deliver a ChildType
like:
class FancyThingsGroup extends Group<FancyThing> …
class Group<ChildType extends Phaser.GameObjects.GameObject = Phaser.GameObjects.GameObject> …
So that all existing classes that use it, can be unchanged.
Both options would allow changing the class StaticGroup
to use extends Phaser.GameObjects.Group<Phaser.Physics.Arcade.Sprite>
(my initial issue).
Classes extending Group
without overriding the return types of the methods is why issues like this happen. Another one:
const group = this.physics.add.staticGroup()
const sprite = group.create(...) // `any`, preferably it should be `Phaser.Types.Physics.Arcade.SpriteWithStaticBody`
I'm not really familiar with tsgen
, but is there a way to override the types of the class being extended?
A workaround that works for me is to manually create the object and add it to the group:
const group = this.physics.add.staticGroup([
this.physics.add.staticSprite(100, 100, "key").setScale(2),
]);
// or
group.add(this.physics.add.staticSprite(100, 100, "key"));
There is absolutely no easy way to do this from the JSDocs and tsgen alone. The code is valid, there are TS sanity work-arounds and that's the only realistic way to achieve this for now, beyond a complete rewrite of Phaser in TS.
Version
Phaser Version: 3.55.2
Operating system: MacOS
Browser: Google Chrome
Description
I wanted to rewrite my JS project to TypeScript. It's running fine, but I have some Type errors from types that come from phaser’s return types. Here is one:
I debugged, and the type of
firstBall
shows asArcadeSprite2
in the browser. I tried to find a type that seems close to that and foundPhaser.Physics.Arcade.Sprite
.So i can workaround with
as
like this:Example Test Code
See the example above.
Additional Information
Phaser.Physics.Arcade.StaticGroup
extends the classGroup
, which defineschildren
.I don’t know much about phaser yet but that is clearly a wrong type. I assume the children of
Phaser.Physics.Arcade.Sprite
are always "ArcadeSprite’s", or if it’s related to whatcreate(…)
does internaly, but ifcreate(…)
has an effect on the childrens type, thenPhaser.Physics.Arcade.StaticGroup
should be generic likeSo that 'Phaser.Physics.Arcade.StaticGroup
can extend
Group` like: