Không Downcasting được trong TypeScript

Xin chào mọi người, mình đang học làm game trên Cocos Creator code bằng type script. Ý tưởng của mình hiện giờ chỉ đơn giản là làm ra một đối tượng để quản lý các đối tượng của game như scene, sound, …
Hiện tại mình đang gặp vấn đề khi downcasting, cụ thể thì

Đầu tiên là Interface của system

export interface ISystemBase{
    setComponent( comp  : Component) : void;
    getComponent() : Component;
    initialize( config : MonoSingletonConfig, onCompleted  : () => void) : void;
}

Sau đó là 1 đối tượng để lưu trữ các MonoSingleton

//Dùng để lưu lại các đối tượng     
const instanceDictionary: { [key: string]: any } = {};

    @ccclass('MonoBehaviour')
    export class MonoSingleton<T1 extends Component, T2> implements ISystemBase {

        protected _component : T1;
        protected _config : T2;

        public static getInstance<T1 extends Component,T2>(typename : string): MonoSingleton<T1,T2> {
            const typeName = typename; // Get the name of the type T1
            if (!instanceDictionary[typeName]) {
                instanceDictionary[typeName] =   new MonoSingleton<T1,T2>()   ;
            }
            return instanceDictionary[typeName] ;
        }
        public setComponent(comp: T1): void {
            this._component =  comp;
        }
        public getComponent(): T1 {
           return this._component;
        }
        public initialize( config : MonoSingletonConfig , onCompleted  : () => void): void {
            if(config){
                console.log(`Load config from ${config.configPath}`);
                resources.load("Cy/Config/"+config.configPath,(err,data) => {
                    if (err) {
                        return;
                    }            
                    this._config = (data as JsonAsset ).json as T2;
                    onCompleted();
                });
            }
        }
    }

Tiếp theo là mình tao 1 cái lớp đế quản lý các scene

@ccclass('SceneManager')
export class SceneManager  extends MonoSingleton<SceneManagerComponent,SceneManagerConfg> {

    public loadFirstScene() : void{
        console.log("load first scene");
    }

}

Và 1 lớp để mình có thể truy cập vào các system

export class GameDirector{
  
    public static SceneManager() : SceneManager {
        return SceneManager.getInstance<SceneManagerComponent,SceneManagerConfg>("SceneManager") as SceneManager;
    }

    public static SoundManager() : SoundManager {
        return SoundManager.getInstance<SoundManagerComponent,SoundManagerConfig>("SoundManager");
    }
}

Tuy nhiên mình đang gặp 1 vấn đề là khi gọi
GameDirector.SceneManager().loadFirstScene();

Thì mình nhận được lỗi là loadFirstScene is not a function. kiểm tra qua thì khi gọi GameDirector.SceneManager() thì trả về là 1 đối tượng của MonoSingleton chứ không phải là SceneManager như mình cast mậc dù SceneManager cũng extends từ MonoSingleton.

Mình đang cố thử để có thể downcast về SceneManager nhưng không thành. Với mình cũng mới vừa học TS, Cocos nên nếu có chỗ nào sai hay vấn đề thì nhờ mn chỉ ra giùm. Mình xin cảm ơn

Code bạn sai ở js rồi chứ k phải là sai ở typescript
Bạn new MonoSingleton thì nó là tạo instance của cái kia thôi, thử new this xem

À mình vừa thử lại thành this thì thấy cái director nó đã trả về là Scene Manager rồi.
instanceDictionary[typeName] = this;
Tuy nhiên nó báo lỗi
(intermediate value)(intermediate value)(intermediate value).SceneManager(...).initialize is not a function
Mình nghĩ là nó ko nhận gọi dc hàm initialize của lớp cha của nó. Đoạn config mình ntn :

 const monoConfig : MonoSingletonConfig = {
                    configPath : this._sceneManagerConfigPath
                }
 GameDirector.SceneManager().initialize(monoConfig,this.initialized.bind(this));

với initialized là hàm gọi chuyển scene sau khi init xong

Tại bạn viết sai rồi chứ sao
Code mẫu js cho bạn, bạn tự thêm type vào cho thành typescript

class Lol {
    static getInstance() {
        if (!this.instance)
            this.instance = new this();
        return this.instance;
    }
    say() {
        console.log("hello");
    }
}
class LolA extends Lol {
}
class LolB extends Lol {
    say() {
        console.log("Hello from B");
    }
}
LolA.getInstance().say();
LolB.getInstance().say();

Không á, mình đâu có biết code bạn sửa ra sao rồi đâu mà chỉ
Bạn đọc lại comment trước với ví dụ rồi tự tìm ra lỗi đi

1 Like

À ok mình giải quyết được rồi, this của js khác với những gì mình biết nên có lỗi thật

instanceDictionary[typeName] = new this();

là dc

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?