Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix lots of type issues in Tween system #16948

Merged
merged 24 commits into from May 16, 2024
Merged

Conversation

dumganhar
Copy link
Contributor

@dumganhar dumganhar commented May 6, 2024

Re: #16937

If developers enable strict mode for their projects and write some code by using tween system like the following:

class MyCustomData {
    constructor (a: number) {
        this._aaa = a;
    }
    _aaa = 0;
}

class TestOne {
    _customData = new MyCustomData(0);

    foo (): void {
        const tweenDuration: number = 1.0;
        const t = tween(this._customData).to(
            tweenDuration,
            new MyCustomData(100),
            this,
        ).start();
    }

    onUpdate (target?: MyCustomData, ratio?: number): void {
        if (target && ratio) {
            // Write the code
        }
    }
}

Before this PR, the above code will trigger a ts compiler error:

Argument of type 'this' is not assignable to parameter of type 'ITweenOption | undefined'.
  Type 'TestOne' is not assignable to type 'ITweenOption'.
    Type 'this' is not assignable to type 'ITweenOption'.
      Type 'TestOne' is not assignable to type 'ITweenOption'.
        Types of property 'onUpdate' are incompatible.
          Type '(target?: MyCustomData | undefined, ratio?: number | undefined) => void' is not assignable to type '(target?: object | undefined, ratio?: number | undefined) => void'.
            Types of parameters 'target' and 'target' are incompatible.
              Type 'object | undefined' is not assignable to type 'MyCustomData | undefined'.
                Property '_aaa' is missing in type '{}' but required in type 'MyCustomData'.ts(2345)
MoveSprite.ts(20, 5): '_aaa' is declared here.
this: this

After apply this PR, the error will disappear, and also we get strong type restriction for target. That means it will trigger an error of type mismatch if the onUpdate target parameter's type is not matched with _this._customData.
For example, we write a wrong code to make the onUpdate target parameter type to Node:

class TestOne {
    _customData = new MyCustomData(0);

    foo (): void {
        const tweenDuration: number = 1.0;
        const t = tween(this._customData).to(
            tweenDuration,
            new MyCustomData(100),
            this,
        ).start();
    }

    onUpdate (target?: Node, ratio?: number): void { // Wrote wrong type of target
        if (target && ratio) {
            // Write the code
        }
    }
}

TS compiler will make an error:

Argument of type 'this' is not assignable to parameter of type 'ITweenOption<MyCustomData> | undefined'.
  Type 'TestOne' is not assignable to type 'ITweenOption<MyCustomData>'.
    Type 'this' is not assignable to type 'ITweenOption<MyCustomData>'.
      Type 'TestOne' is not assignable to type 'ITweenOption<MyCustomData>'.
        Types of property 'onUpdate' are incompatible.
          Type '(target?: Node | undefined, ratio?: number | undefined) => void' is not assignable to type '(target?: MyCustomData | undefined, ratio?: number | undefined) => void'.
            Types of parameters 'target' and 'target' are incompatible.
              Type 'MyCustomData | undefined' is not assignable to type 'Node | undefined'.
                Type 'MyCustomData' is missing the following properties from type 'Node': components, _persistNode, name, uuid, and 124 more.ts(2345)
this: this

That's the reason why we don't change the onUpdate (target?: object) to onUpdate (target?: any) since any is the loosest type which doesn't have any restrictions. The any keyword needs to be avoided as much as possible.

Changelog


Continuous Integration

This pull request:

  • needs automatic test cases check.

    Manual trigger with @cocos-robot run test cases afterward.

  • does not change any runtime related code or build configuration

    If any reviewer thinks the CI checks are needed, please uncheck this option, then close and reopen the issue.


Compatibility Check

This pull request:

  • changes public API, and have ensured backward compatibility with deprecated features.
  • affects platform compatibility, e.g. system version, browser version, platform sdk version, platform toolchain, language version, hardware compatibility etc.
  • affects file structure of the build package or build configuration which requires user project upgrade.
  • introduces breaking changes, please list all changes, affected features and the scope of violation.

@dumganhar dumganhar requested a review from minggo May 6, 2024 11:16
cocos/tween/export-api.ts Outdated Show resolved Hide resolved

/**
* @en
* A callback that is triggered when a tween action is update.
* @zh
* 回调,当缓动动作更新时触发。
*/
onUpdate?: (target?: object, ratio?: number) => void;
onUpdate?: (target?: T, ratio?: number) => void;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callback target is generic now rather than object type.

Copy link

github-actions bot commented May 6, 2024

Interface Check Report

! WARNING this pull request has changed these public interfaces:

@@ -54565,17 +54565,17 @@
      *   .call(() => { console.log('This is a callback'); })
      *   .by(1, {scale: new Vec3(-1, -1, -1)}, {easing: 'sineOutIn'})
      *   .start()
      */
-    export function tween<T>(target?: T): Tween<T>;
+    export function tween<T extends object = any>(target?: T): Tween<T>;
     /**
      * @en
      * tweenUtil is a utility function that helps instantiate Tween instances.
      * @zh
      * tweenUtil 是一个工具函数,帮助实例化 Tween 实例。
      * @deprecated please use `tween` instead.
      */
-    export function tweenUtil<T>(target?: T): Tween<T>;
+    export function tweenUtil<T extends object = any>(target?: T): Tween<T>;
     /**
      * @en
      * Tween provide a simple and flexible way to action, It's transplanted from cocos creator。
      * @zh
@@ -54588,9 +54588,9 @@
      *   .call(() => { console.log('This is a callback'); })
      *   .by(1, {scale: new Vec3(-1, -1, -1), position: new Vec3(-5, -5, -5)}, {easing: 'sineOutIn'})
      *   .start()
      */
-    export class Tween<T> {
+    export class Tween<T extends object = any> {
         constructor(target?: T | null);
         /**
          * @en Sets tween tag
          * @zh 设置缓动的标签
@@ -54599,9 +54599,9 @@
          */
         tag(tag: number): Tween<T>;
         /**
          * @en
-         * Insert an action or tween to this sequence.
+         * Insert a tween to this sequence.
          * @zh
          * 插入一个 tween 到队列中。
          * @method then
          * @param other @en The rear tween of this tween @zh 当前缓动的后置缓动
@@ -54614,9 +54614,9 @@
          * 设置 tween 的 target。
          * @method target
          * @param target @en The target of this tween @zh 当前缓动的目标对象
          */
-        target(target: T): Tween<T | undefined>;
+        target<U extends object = any>(target: U): Tween<U>;
         /**
          * @en
          * Start this tween.
          * @zh
@@ -54637,9 +54637,9 @@
          * 克隆当前 tween。
          * @method clone
          * @param target @en The target of clone tween @zh 克隆缓动的目标对象
          */
-        clone(target: T): Tween<T>;
+        clone<U extends object = any>(target: U): Tween<U>;
         /**
          * @en
          * Integrate all previous actions to an action.
          * @zh
@@ -54657,9 +54657,9 @@
          * @param opts @en Optional functions of tween @zh 可选的缓动功能
          * @param opts.progress @en Interpolation function @zh 缓动的速度插值函数
          * @param opts.easing @en Tween function or a lambda @zh 缓动的曲线函数或lambda表达式
          */
-        to(duration: number, props: __private._cocos_tween_tween__ConstructorType<T>, opts?: ITweenOption): Tween<T>;
+        to(duration: number, props: __private._cocos_tween_tween__ConstructorType<T>, opts?: ITweenOption<T>): Tween<T>;
         /**
          * @en
          * Add an action which calculates with relative value.
          * @zh
@@ -54671,9 +54671,9 @@
          * @param [opts.progress]
          * @param [opts.easing]
          * @return {Tween}
          */
-        by(duration: number, props: __private._cocos_tween_tween__ConstructorType<T>, opts?: ITweenOption): Tween<T>;
+        by(duration: number, props: __private._cocos_tween_tween__ConstructorType<T>, opts?: ITweenOption<T>): Tween<T>;
         /**
          * @en
          * Directly set target properties.
          * @zh
@@ -54699,11 +54699,13 @@
          * @zh
          * 添加一个回调 action。
          * @method call
          * @param callback @en Callback function at the end of this tween @zh 当前缓动结束时的回调函数
+         * @param callbackThis @en The this object in callback function @zh 回调函数中的 this 对象
+         * @param data @en The Custom data that will be passed to callback @zh 要传递给回调函数的自定义数据
          * @return {Tween}
          */
-        call(callback: Function): Tween<T>;
+        call<TCallbackThis, TData>(callback: __private._cocos_tween_actions_action_instant__TCallFuncCallback<T, TData>, callbackThis?: TCallbackThis, data?: TData): Tween<T>;
         /**
          * @en
          * Add a sequence action.
          * @zh
@@ -54756,30 +54758,30 @@
          * Add a hide action, only for node target.
          * @zh
          * 添加一个隐藏 action,只适用于 target 是节点类型的。
          */
-        hide(): Tween<T>;
+        hide(): __private._cocos_tween_tween__TweenWithNodeTargetOrUnknown<T>;
         /**
          * @en
          * Add a show action, only for node target.
          * @zh
          * 添加一个显示 action,只适用于 target 是节点类型的。
          */
-        show(): Tween<T>;
+        show(): __private._cocos_tween_tween__TweenWithNodeTargetOrUnknown<T>;
         /**
          * @en
          * Add a removeSelf action, only for node target.
          * @zh
          * 添加一个移除自己 action,只适用于 target 是节点类型的。
          */
-        removeSelf(): Tween<T>;
+        removeSelf(): __private._cocos_tween_tween__TweenWithNodeTargetOrUnknown<T>;
         /**
          * @en
          * Add a destroySelf action, only for node target.
          * @zh
          * 添加一个移除并销毁自己 action,只适用于 target 是节点类型的。
          */
-        destroySelf(): Tween<T>;
+        destroySelf(): __private._cocos_tween_tween__TweenWithNodeTargetOrUnknown<T>;
         /**
          * @en
          * Stop all tweens
          * @zh
@@ -54800,12 +54802,12 @@
          * 停止所有指定对象的缓动
          */
         static stopAllByTarget(target?: object): void;
     }
-    export class TweenAction extends __private._cocos_tween_actions_action_interval__ActionInterval {
-        constructor(duration: number, props: any, opts?: ITweenOption);
-        clone(): TweenAction;
-        startWithTarget(target: Record<string, unknown>): void;
+    export class TweenAction<T> extends __private._cocos_tween_actions_action_interval__ActionInterval {
+        constructor(duration: number, props: any, opts?: ITweenOption<T>);
+        clone(): TweenAction<T>;
+        startWithTarget<U>(target: U | undefined): void;
         update(t: number): void;
         progress(start: number, end: number, current: number, t: number): number;
     }
     /**
@@ -54820,9 +54822,9 @@
      * The interface of optional property.
      * @zh
      * 缓动的可选属性的接口定义。
      */
-    export interface ITweenOption {
+    export interface ITweenOption<T> {
         /**
          * @en
          * Easing function, you can pass in a string or custom function.
          * @zh
@@ -54830,8 +54832,15 @@
          */
         easing?: TweenEasing | ((k: number) => number);
         /**
          * @en
+         * Whether to use relative value calculation method during easing process
+         * @zh
+         * 缓动过程中是否采用相对值计算的方法
+         */
+        relative?: boolean;
+        /**
+         * @en
          * Interpolation function, you can pass in a custom function.
          * @zh
          * 插值函数,参数的意义 start:起始值,end:目标值,current:当前值,ratio:当前进度
          */
@@ -54841,23 +54850,23 @@
          * A callback that is triggered when a tween action is started.
          * @zh
          * 回调,当缓动动作启动时触发。
          */
-        onStart?: (target?: object) => void;
+        onStart?: (target?: T) => void;
         /**
          * @en
          * A callback that is triggered when a tween action is update.
          * @zh
          * 回调,当缓动动作更新时触发。
          */
-        onUpdate?: (target?: object, ratio?: number) => void;
+        onUpdate?: (target?: T, ratio?: number) => void;
         /**
          * @en
          * A callback that is triggered when a tween action is completed.
          * @zh
          * 回调,当缓动动作完成时触发。
          */
-        onComplete?: (target?: object) => void;
+        onComplete?: (target?: T) => void;
     }
     /**
      * @en
      * Button component. Can be pressed or clicked. Button has 4 Transition types:
@@ -68798,19 +68807,19 @@
          * @en Base classAction for action classes.
          * @zh Action 类是所有动作类型的基类。
          * @class Action
          */
-        export class _cocos_tween_actions_action__Action {
+        export abstract class _cocos_tween_actions_action__Action {
             /**
              * @en Default Action tag.
              * @zh 默认动作标签。
              * @constant
              * @static
              * @default -1
              */
             static TAG_INVALID: number;
-            protected originalTarget: Node | null;
-            protected target: Node | null;
+            protected originalTarget: unknown;
+            protected target: unknown;
             protected tag: number;
             /**
              * @en
              * to copy object with deep copy.
@@ -68818,18 +68827,18 @@
              * @zh 返回一个克隆的动作。
              * @method clone
              * @return {Action}
              */
-            clone(): _cocos_tween_actions_action__Action;
+            abstract clone(): _cocos_tween_actions_action__Action;
             /**
              * @en
              * return true if the action has finished.
              * @zh 如果动作已完成就返回 true。
              * @method isDone
              * @return {Boolean}
              */
             isDone(): boolean;
-            startWithTarget(target: any): void;
+            startWithTarget<T>(target: T | null): void;
             stop(): void;
             step(dt: number): void;
             update(dt: number): void;
             /**
@@ -68837,24 +68846,24 @@
              * @zh 获取当前目标节点。
              * @method getTarget
              * @return {object}
              */
-            getTarget(): Node | null;
+            getTarget<T>(): T | null;
             /**
              * @en The action will modify the target properties.
              * @zh 设置目标节点。
              * @method setTarget
              * @param {object} target
              */
-            setTarget(target: Node): void;
+            setTarget<T>(target: T): void;
             /**
              * @en get the original target.
              * @zh 获取原始目标节点。
              * @method getOriginalTarget
              * @return {object}
              */
-            getOriginalTarget(): Node | null;
-            setOriginalTarget(originalTarget: any): void;
+            getOriginalTarget<T>(): T | null;
+            setOriginalTarget<T>(originalTarget: T): void;
             /**
              * @en get tag number.
              * @zh 获取用于识别动作的标签。
              * @method getTag
@@ -68878,30 +68887,31 @@
              * @zh 返回一个新的动作,执行与原动作完全相反的动作。
              * @method reverse
              * @return {Action | null}
              */
-            reverse(): _cocos_tween_actions_action__Action | null;
-            retain(): void;
-            release(): void;
+            abstract reverse(): _cocos_tween_actions_action__Action | null;
         }
+        export class _cocos_tween_actions_action_manager__HashElement {
+            actions: _cocos_tween_actions_action__Action[];
+            target: unknown;
+            actionIndex: number;
+            currentAction: _cocos_tween_actions_action__Action | null;
+            paused: boolean;
+            lock: boolean;
+        }
         /**
          * @en
          * `ActionManager` is a class that can manage actions.<br/>
-         * Normally you won't need to use this class directly. 99% of the cases you will use the CCNode interface,
+         * Normally you won't need to use this class directly. 99% of the cases you will use the `Tween` interface,
          * which uses this class's singleton object.
-         * But there are some cases where you might need to use this class. <br/>
-         * Examples:<br/>
-         * - When you want to run an action where the target is different from a CCNode.<br/>
          * - When you want to pause / resume the actions<br/>
          * @zh
          * `ActionManager` 是可以管理动作的单例类。<br/>
-         * 通常你并不需要直接使用这个类,99%的情况您将使用 CCNode 的接口。<br/>
+         * 通常你并不需要直接使用这个类,99%的情况您将使用 `Tween` 的接口。<br/>
          * 但也有一些情况下,您可能需要使用这个类。 <br/>
          * 例如:
-         *  - 当你想要运行一个动作,但目标不是 CCNode 类型时。 <br/>
          *  - 当你想要暂停/恢复动作时。 <br/>
          * @class ActionManager
-         * @example {@link cocos2d/core/CCActionManager/ActionManager.js}
          */
         export class _cocos_tween_actions_action_manager__ActionManager {
             /**
              * @en
@@ -68920,9 +68930,9 @@
              * @param {Action} action
              * @param {object} target
              * @param {Boolean} paused
              */
-            addAction(action: _cocos_tween_actions_action__Action, target: Node, paused: boolean): void;
+            addAction<T>(action: _cocos_tween_actions_action__Action | null, target: T, paused: boolean): void;
             /**
              * @en Removes all actions from all the targets.
              * @zh 移除所有对象的所有动作。
              * @method removeAllActions
@@ -68935,51 +68945,51 @@
              * @zh
              * 移除指定对象上的所有动作。<br/>
              * 属于该目标的所有的动作将被删除。
              * @method removeAllActionsFromTarget
-             * @param {Node} target
+             * @param {T} target
              */
-            removeAllActionsFromTarget(target: Node): void;
+            removeAllActionsFromTarget<T>(target: T): void;
             /**
              * @en Removes an action given an action reference.
              * @zh 移除指定的动作。
              * @method removeAction
              * @param {Action} action
              */
-            removeAction(action: _cocos_tween_actions_action__Action): void;
+            removeAction(action: _cocos_tween_actions_action__Action | null): void;
             /**
              * @internal
              */
-            _removeActionByTag(tag: number, element: any, target?: Node): void;
+            _removeActionByTag<T>(tag: number, element: _cocos_tween_actions_action_manager__HashElement, target?: T): void;
             /**
              * @internal
              */
-            _removeAllActionsByTag(tag: number, element: any, target?: Node): void;
+            _removeAllActionsByTag<T>(tag: number, element: _cocos_tween_actions_action_manager__HashElement, target?: T): void;
             /**
              * @en Removes an action given its tag and the target.
              * @zh 删除指定对象下特定标签的一个动作,将删除首个匹配到的动作。
              * @method removeActionByTag
              * @param {Number} tag
-             * @param {Node} target
+             * @param {T} target
              */
-            removeActionByTag(tag: number, target?: Node): void;
+            removeActionByTag<T>(tag: number, target?: T): void;
             /**
              * @en Removes all actions given the tag and the target.
              * @zh 删除指定对象下特定标签的所有动作。
              * @method removeAllActionsByTag
              * @param {Number} tag
-             * @param {Node} target
+             * @param {T} target
              */
-            removeAllActionsByTag(tag: number, target?: Node): void;
+            removeAllActionsByTag<T>(tag: number, target?: T): void;
             /**
              * @en Gets an action given its tag an a target.
              * @zh 通过目标对象和标签获取一个动作。
              * @method getActionByTag
              * @param {Number} tag
-             * @param {Node} target
+             * @param {T} target
              * @return {Action|null}  return the Action with the given tag on success
              */
-            getActionByTag(tag: number, target: Node): _cocos_tween_actions_action__Action | null;
+            getActionByTag<T>(tag: number, target: T): _cocos_tween_actions_action__Action | null;
             /**
              * @en
              * Returns the numbers of actions that are running in a certain target. <br/>
              * Composable actions are counted as 1 action. <br/>
@@ -68993,47 +69003,47 @@
              *  - 如果您正在运行 7 个动作组成的序列动作(Sequence),这个函数将返回 1。<br/>
              *  - 如果你正在运行 2 个序列动作(Sequence)和 5 个普通动作,这个函数将返回 7。<br/>
              *
              * @method getNumberOfRunningActionsInTarget
-             * @param {Node} target
+             * @param {T} target
              * @return {Number}
              */
-            getNumberOfRunningActionsInTarget(target: Node): number;
+            getNumberOfRunningActionsInTarget<T>(target: T): number;
             /**
              * @en Pauses the target: all running actions and newly added actions will be paused.
              * @zh 暂停指定对象:所有正在运行的动作和新添加的动作都将会暂停。
              * @method pauseTarget
-             * @param {Node} target
+             * @param {T} target
              */
-            pauseTarget(target: Node): void;
+            pauseTarget<T>(target: T): void;
             /**
              * @en Resumes the target. All queued actions will be resumed.
              * @zh 让指定目标恢复运行。在执行序列中所有被暂停的动作将重新恢复运行。
              * @method resumeTarget
-             * @param {Node} target
+             * @param {T} target
              */
-            resumeTarget(target: Node): void;
+            resumeTarget<T>(target: T): void;
             /**
              * @en Pauses all running actions, returning a list of targets whose actions were paused.
              * @zh 暂停所有正在运行的动作,返回一个包含了那些动作被暂停了的目标对象的列表。
              * @method pauseAllRunningActions
              * @return {Array}  a list of targets whose actions were paused.
              */
-            pauseAllRunningActions(): Array<any>;
+            pauseAllRunningActions(): unknown[];
             /**
              * @en Resume a set of targets (convenience function to reverse a pauseAllRunningActions or pauseTargets call).
              * @zh 让一组指定对象恢复运行(用来逆转 pauseAllRunningActions 效果的便捷函数)。
              * @method resumeTargets
              * @param {Array} targetsToResume
              */
-            resumeTargets(targetsToResume: Array<any>): void;
+            resumeTargets<T>(targetsToResume: Array<T>): void;
             /**
              * @en Pause a set of targets.
              * @zh 暂停一组指定对象。
              * @method pauseTargets
              * @param {Array} targetsToPause
              */
-            pauseTargets(targetsToPause: Array<any>): void;
+            pauseTargets<T>(targetsToPause: Array<T>): void;
             /**
              * @en
              * purges the shared action manager. It releases the retained instance. <br/>
              * because it uses this, so it can not be static.
@@ -69059,8 +69069,10 @@
             [P in K]?: T[P];
         };
         export type _cocos_tween_tween__OmitType<Base, Type> = _cocos_tween_tween__KeyPartial<Base, _cocos_tween_tween__AllowedNames<Base, Type>>;
         export type _cocos_tween_tween__ConstructorType<T> = _cocos_tween_tween__OmitType<T, Function>;
+        export type _cocos_tween_actions_action_instant__TCallFuncCallback<TTarget, TData> = (target?: TTarget, data?: TData) => void;
+        export type _cocos_tween_tween__TweenWithNodeTargetOrUnknown<T> = T extends Node ? Tween<T> : unknown;
         /**
          * @en
          * Base class actions that do have a finite time duration. <br/>
          * Possible actions: <br/>
@@ -69071,9 +69083,9 @@
          * @zh 有限时间动作,这种动作拥有时长 duration 属性。
          * @class FiniteTimeAction
          * @extends Action
          */
-        export class _cocos_tween_actions_action__FiniteTimeAction extends _cocos_tween_actions_action__Action {
+        export abstract class _cocos_tween_actions_action__FiniteTimeAction extends _cocos_tween_actions_action__Action {
             _duration: number;
             _timesForRepeat: number;
             /**
              * @en get duration of the action. (seconds).
@@ -69090,15 +69102,16 @@
              */
             setDuration(duration: number): void;
             /**
              * @en
-             * to copy object with deep copy.
-             * returns a clone of action.
-             * @zh 返回一个克隆的动作。
+             * To copy object with deep copy.
+             * returns a clone of FiniteTimeAction.
+             * @zh 返回一个克隆的有限时间动作。
              * @method clone
              * @return {FiniteTimeAction}
              */
-            clone(): _cocos_tween_actions_action__FiniteTimeAction;
+            abstract clone(): _cocos_tween_actions_action__FiniteTimeAction;
+            abstract reverse(): _cocos_tween_actions_action__FiniteTimeAction;
         }
         /**
          * @en
          * <p> An interval action is an action that takes place within a certain period of time. <br/>
@@ -69116,13 +69129,12 @@
          * @class ActionInterval
          * @extends FiniteTimeAction
          * @param {Number} d duration in seconds
          */
-        export class _cocos_tween_actions_action_interval__ActionInterval extends _cocos_tween_actions_action__FiniteTimeAction {
+        export abstract class _cocos_tween_actions_action_interval__ActionInterval extends _cocos_tween_actions_action__FiniteTimeAction {
             protected MAX_VALUE: number;
             protected _elapsed: number;
             protected _firstTick: boolean;
-            protected _easeList: Function[];
             protected _speed: number;
             protected _repeatForever: boolean;
             _repeatMethod: boolean;
             protected _speedMethod: boolean;
@@ -69130,26 +69142,13 @@
             getElapsed(): number;
             initWithDuration(d: number): boolean;
             isDone(): boolean;
             _cloneDecoration(action: _cocos_tween_actions_action_interval__ActionInterval): void;
-            _reverseEaseList(action: _cocos_tween_actions_action_interval__ActionInterval): void;
-            clone(): _cocos_tween_actions_action_interval__ActionInterval;
-            /**
-             * @en Implementation of ease motion.
-             * @zh 缓动运动。
-             * @method easing
-             * @param {Object} easeObj
-             * @returns {ActionInterval}
-             * @example
-             * import { easeIn } from 'cc';
-             * action.easing(easeIn(3.0));
-             */
-            easing(easeObj: any): _cocos_tween_actions_action_interval__ActionInterval;
-            _computeEaseTime(dt: any): any;
+            abstract clone(): _cocos_tween_actions_action_interval__ActionInterval;
             step(dt: number): void;
-            startWithTarget(target: any): void;
+            startWithTarget<T>(target: T | null): void;
             reverse(): _cocos_tween_actions_action_interval__ActionInterval;
-            setAmplitudeRate(amp: any): void;
+            setAmplitudeRate(amp: number): void;
             getAmplitudeRate(): number;
             /**
              * @en
              * Changes the speed of an action, making it take longer (speed>1)

@@ -197,7 +197,7 @@ export function sineInOut (k: number): number {
* @zh 启动慢,加速快。具体效果可以参考[该文档](https://docs.cocos.com/creator/manual/zh/tween/tween-function.html)。
*/
export function expoIn (k: number): number {
return k === 0 ? 0 : Math.pow(1024, k - 1);
return k === 0 ? 0 : 1024 ** (k - 1);
Copy link
Contributor Author

@dumganhar dumganhar May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the error:

'Math.pow' is restricted from being used. Use the exponentiation operator (**) instead.eslint[no-restricted-properties](https://eslint.org/docs/latest/rules/no-restricted-properties)
Use the '**' operator instead of 'Math.pow'.eslint[prefer-exponentiation-operator](https://eslint.org/docs/latest/rules/prefer-exponentiation-operator)

@@ -70,8 +70,8 @@ export class ActionInstant extends FiniteTimeAction {
* @extends ActionInstant
*/
export class Show extends ActionInstant {
update (dt: any): void {
const _renderComps = this.target!.getComponentsInChildren(Renderer);
update (_dt: number): void {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding _ for dt name is because we need to fix the unused warning:

'dt' is declared but its value is never read.ts(6133)
(parameter) dt: number

// filtering if it not a number
// eslint-disable-next-line no-restricted-globals
if (isNaN(_t[k])) continue;
if (Number.isNaN(_t[k] as number)) continue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix :

Unexpected use of 'isNaN'. Use Number.isNaN instead https://github.com/airbnb/javascript#standard-library--isnaneslint[no-restricted-globals](https://eslint.org/docs/latest/rules/no-restricted-globals)

@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

startWithTarget (target: Record<string, unknown>): void {
ActionInterval.prototype.startWithTarget.call(this, target);
startWithTarget<U> (target: U | undefined): void {
const isEqual: TypeEquality<T, U> = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we ensure the two target type should be the same.

@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

this._actions.push(other.clone());
} else {
this._actions.push(other._union());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then only accesses Tween<T>, if passing an Action, I added another private method insertAction for that.

@@ -100,7 +104,7 @@ export class Tween<T> {
* @method target
* @param target @en The target of this tween @zh 当前缓动的目标对象
*/
target (target: T): Tween<T | undefined> {
target (target: T): Tween<T> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is Tween<T> type, I don't know why it returned Tween<T | undefined> before.

call (callback: Function): Tween<T> {
const action = callFunc(callback);
call<TCallbackThis, TData> (callback: TCallFuncCallback<T, TData>, callbackThis?: TCallbackThis, data?: TData): Tween<T> {
const action = callFunc(callback, callbackThis, data);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Support for custom this and data for call tween. Usages:

class MyCallFuncTarget {
    foo (target?: Node, data?: number): void {
        // data should be 123, this should be the `MyCallFuncTarget` instance.
    }
}

const myCallfuncTarget = new MyCallFuncTarget();

tween(node)
    .sequence()
    .to(0.1, { position: v3(0, 0, 0) }, {
        onUpdate: (current?: Node, ratio?: number): void => {},
    })
    .call(myCallfuncTarget.foo, myCallfuncTarget, 123)
    .start();

const action = hide();
this._actions.push(action);
return this;
hide (): TweenWithNodeTargetOrUnknown<T> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hide will return unknown type if the target is not Node type. And ts compiler will also trigger an error like:

Argument of type 'unknown' is not assignable to parameter of type 'Tween<MyCustomData>'.ts(2345)

@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

}

private _getElement (target: Record<string, unknown>, paused: boolean): HashElement {
private _getElement<T> (target: T, paused: boolean): HashElement {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change type from Record<string, unknown> to T? It seems Record<string, unknown> is a more clear type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target is a generic (template) type T but Record<string, unknown> means { 'str': unknown }

@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

@dumganhar dumganhar closed this May 10, 2024
@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

1 similar comment
@sushanhong
Copy link

@cocos-robot run test cases

@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

4 similar comments
@sushanhong
Copy link

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

3 similar comments
@dumganhar
Copy link
Contributor Author

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

@sushanhong
Copy link

@cocos-robot run test cases

@dumganhar dumganhar merged commit ead9ae0 into cocos:v3.8.5 May 16, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants