#7353·phaser

`BaseTween#callbacks` type is inconsistent with runtime behaviour

Author: Bertie690Created Aug 18, 2026Updated Aug 18, 2026

Version

  • Phaser Version: N/A (Occurs on master)
  • Operating system: N/A
  • Browser: N/A

Description

The type for callbacks is incorrect - instead of a partial object that might have each callback, it's an object that ALWAYS has every single callback (though each may be set to null).

https://github.com/phaserjs/phaser/blob/41be1e462bc600064e498cba370bfa8c5c055a22/src/tweens/tween/BaseTween.js#L220-L231

MOREOVER, the data added by setCallback is NOT a simple lambda function! It's an object containing the extra parameters! https://github.com/phaserjs/phaser/blob/41be1e462bc600064e498cba370bfa8c5c055a22/src/tweens/tween/BaseTween.js#L621-L624

This is BLATANTLY type-unsafe due to effectively misrepresenting the type's very nature - the declaration file says "record of lambda functions", the code says "record of objects with lambda functions".

Current (incorrect) typing

typescript
type TweenCallbacks = {
  /**
   * A function to call when the tween becomes active within the Tween Manager.
   */
  onActive?: Phaser.Types.Tweens.TweenOnActiveCallback;
  /**
   * A function to call when the tween starts playback, after any delays have expired.
   */
  onStart?: Phaser.Types.Tweens.TweenOnStartCallback;
  /**
   * A function to call when the tween completes.
   */
  onComplete?: Phaser.Types.Tweens.TweenOnCompleteCallback;
  /**
   * A function to call each time the tween loops.
   */
  onLoop?: Phaser.Types.Tweens.TweenOnLoopCallback;
  /**
   * A function to call each time the tween is paused.
   */
  onPause?: Phaser.Types.Tweens.TweenOnPauseCallback;
  /**
   * A function to call each time the tween is resumed.
   */
  onResume?: Phaser.Types.Tweens.TweenOnResumeCallback;
  /**
   * A function to call each time the tween repeats. Called once per property per target.
   */
  onRepeat?: Phaser.Types.Tweens.TweenOnRepeatCallback;
  /**
   * A function to call when the tween is stopped.
   */
  onStop?: Phaser.Types.Tweens.TweenOnStopCallback;
  /**
   * A function to call each time the tween steps. Called once per property per target.
   */
  onUpdate?: Phaser.Types.Tweens.TweenOnUpdateCallback;
  /**
   * A function to call each time the tween yoyos. Called once per property per target.
   */
  onYoyo?: Phaser.Types.Tweens.TweenOnYoyoCallback;
};

Example Test Code

typescript
const tween = scene.tweens.add({targets: sprite, duration: 400, on});
if (tween.callbacks.onComplete === null) {} // TS says impossible, but actually runs
tween.callbacks.onComplete?.() // CRASHES because it's not a function!

Additional Information

The callbacks themselves should also probably be readonly, given the setCallback function's entire purpose is to modify them.