从Typescript中的非静态方法中调用静态方法

时间:2018-10-09 16:00:44

标签: typescript static-methods template-method-pattern

我的所有层次结构中都有一些静态内容(在此示例中为_image)。我希望能够访问通讯员_image而不必重复代码:

这很好:

class Actor {
    static _image; // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(this.class._image); //doesn't work....
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}

但是它不起作用。现在我只能去:

class Actor {
}

class GoodActor extends Actor {
    static _image = 'good.png'  // I need it to be static

    method show(){   // I need it to be non-static
        this.setImage(GoodActor._image);
    }
}

class BadActor extends Actor {
    static _image = 'bad.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(BadActor._image);
    }
}

class MediumActor extends Actor {
    static _image = 'medium.png'  // I need it to be static

    method show(){  // I need it to be non-static
        this.setImage(MediumActor._image);
    }
}

假设这四个类具有更多方法。我不想在每个子类中都重复使用show()方法...但是我需要show()方法变为非静态_image将被静态访问

我已经阅读过此问题https://github.com/Microsoft/TypeScript/issues/7673,但是很遗憾,我无法在此提出要求,因为他们已经关闭了该问题而未进行修复。他们都没有谈到需要动态解析要调用的静态方法的问题。

2 个答案:

答案 0 :(得分:3)

更新:为什么不想要在缓存图像之前构造单个对象?如果您使建筑便宜,那么使用静态字段就没有任何好处。

示例:

class Actor {
    image: string;

    showImage() {
        console.log(this.image);
    }
}


class GoodActor extends Actor {
    image = 'good.png';
}

class BadActor extends Actor {
    image = 'bad.png';
}

const myActorTypes: (typeof Actor)[] = [GoodActor, BadActor];

function preloadImages() {
    for (let myActorType of myActorTypes) {
        preloadImage(new myActorType().image);
    }
}

function preloadImage(image: string) {
    console.log(`Loading ${image}`);
}

preloadImages();

// "Loading good.png"
// "Loading bad.png"

在注释中添加澄清之前的答案:

不幸的是,这行不通。在运行时,您无法引用对象的类,因此,如果您只有对象,但没有引用类型,则无法访问静态字段。

但是,我会质疑为什么需要一个静态字段。正如我在评论中所写的那样,我从未见过将静态字段用于实际变量或对象层次结构/继承的一部分的好案例。

我不明白您的确切原因,但是可能的解决方法可能是将特定的Actor类传递到您的主要Actor类中,并像这样引用静态字段。

type ActorType = { _image: string };

class Actor {
    static _image; // I need it to be static

    actorType: ActorType = null;

    constructor(actorType: ActorType) {
        this.actorType = actorType;
    }

    setImage(image) {
        console.log(`Set image to ${image}`);
    }

    show(){  // I need it to be non-static
        this.setImage(this.actorType._image); //doesn't work....
    }
}

class GoodActor {
    static _image = 'good.png'
}

class BadActor {
    static _image = 'bad.png'
}

class MediumActor {
    static _image = 'medium.png'
}

const actor = new Actor(GoodActor);
actor.show();
// "Set image to good.png"
const actor2 = new Actor(BadActor);
actor2.show();
// "Set image to bad.png"

答案 1 :(得分:1)

FTR,您可以访问当前对象的类。它称为constructor,而不是class,并且您需要对其进行声明,以使其具有比Function更有用的类型。

class Actor {
    static _image: string; // I need it to be static

    // Keep static members, remove construct signature because
    // subclasses may define constructors with different parameters. 
    "constructor": Pick<typeof Actor, keyof typeof Actor>;

    show(){  // I need it to be non-static
        this.setImage(this.constructor._image);
    }
}

class GoodActor extends Actor {
    static _image = 'good.png'
}

class BadActor extends Actor {
    static _image = 'bad.png'
}

class MediumActor extends Actor {
    static _image = 'medium.png'
}