Фабрика союзного типа без литья по типу - PullRequest
0 голосов
/ 30 июня 2018
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. Свойство infantField отсутствует в типе PassengerAdult.

Могу ли я каким-то образом заставить машинопись понять, что он возвращает внутри createPassenger метода? Я знаю, что в строке вызова я бы разыграл результат как

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

но я бы хотел этого избежать.

1 Ответ

0 голосов
/ 30 июня 2018

Да, вы можете описать тип возвращаемого значения, который зависит от литерального значения, с помощью объявлений перегрузки. Вам нужно добавить все три объявления для 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 Вот полный пример, который выдает ошибку для последней строки: «Аргумент типа« логический »не может быть назначен параметру типа« 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); 
...