联合式无型铸造厂

Factory of union type without type casting

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); 

我收到一个错误

Type 'PassengerAdult | PassengerInfant' is not assignable to type 'PassengerInfant'. Type 'PassengerAdult' is not assignable to type 'PassengerInfant'. Property 'infantField' is missing in type 'PassengerAdult'.

我能否以某种方式强制打字稿理解他在 createPassenger 方法中返回的内容?我知道在调用行中我会将结果转换为

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

但我想避免这种情况。

是的,您可以描述 return 类型,该类型依赖于带有重载声明的文字值。您需要为 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); 

update 这是给出最后一行错误的完整示例:"Argument of type 'boolean' is not assignable to parameter of type '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);