首页 > 解决方案 > 无铸型联合式工厂

问题描述

abstract class Passenger {
    passengerKey: string;
}

class PassengerAdult extends Passenger {
    adultField: string;
}

class PassengerInfant extends Passenger {
    infantField: string;
}

class PassengerFactory {
    static createPassenger(isInfant: boolean): PassengerAdult | PassengerInfant {
        if (isInfant) {
            return new PassengerInfant();
        }

        return new PassengerAdult();
    }
}

const passengerInfant: PassengerInfant = PassengerFactory.createPassenger(true); 

我收到一个错误

输入'PassengerAdult | PassengerInfant' 不能分配给类型 'PassengerInfant'。“PassengerAdult”类型不能分配给“PassengerInfant”类型。“PassengerAdult”类型中缺少属性“infantField”。

我可以以某种方式强制打字稿理解他在createPassenger方法内部返回的内容吗?我知道在调用行中我会像这样

const passengerInfant: PassengerInfant = <PassengerInfant>PassengengerFactory...

但我想避免这种情况。

标签: typescriptdesign-patternsfactory

解决方案


是的,您可以使用重载声明来描述取决于文字值的返回类型。您需要添加所有三个声明,createPassenger因为实现签名不参与重载解析 - 如果没有第三个声明,具有非文字值的调用将无法编译。

class PassengerFactory {
    static createPassenger(isInfant: false): PassengerAdult;
    static createPassenger(isInfant: true): PassengerInfant;
    static createPassenger(isInfant: boolean): PassengerAdult | PassengerInfant;
    static createPassenger(isInfant: boolean): PassengerAdult | PassengerInfant {
        if (isInfant) {
            return new PassengerInfant();
        }

        return new PassengerAdult();
    }
}

const passengerInfant: PassengerInfant = PassengerFactory.createPassenger(true);
const passengerRandom: Passenger = PassengerFactory.createPassenger(Math.random() > 0.5); 

此处更新是给出最后一行错误的完整示例:“'boolean' 类型的参数不可分配给 'true' 类型的参数。”:

abstract class Passenger {
    passengerKey: string;
}

class PassengerAdult extends Passenger {
    adultField: string;
}

class PassengerInfant extends Passenger {
    infantField: string;
}

class PassengerFactory {
    static createPassenger(isInfact: false): PassengerAdult;
    static createPassenger(isInfant: true): PassengerInfant;
    static createPassenger(isInfant: boolean): PassengerAdult | PassengerInfant {
        if (isInfant) {
            return new PassengerInfant();
        }

        return new PassengerAdult();
    }
}

const passengerInfant: PassengerInfant = PassengerFactory.createPassenger(true);
const passengerRandom: Passenger = PassengerFactory.createPassenger(Math.random() > 0.5); 

推荐阅读