cocos-engine icon indicating copy to clipboard operation
cocos-engine copied to clipboard

Fix lots of type issues in Tween system

Open dumganhar opened this issue 2 months ago • 20 comments

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 avatar May 06 '24 11:05 dumganhar