Как добавить охранников расширений к условным типам? Или эквивалент - PullRequest
0 голосов
/ 13 июля 2020

Допустим, у меня есть класс с параметром generi c. У него есть условные типы для некоторых свойств класса. Эти условные типы зависят от того, является ли параметр generi c одним из двух возможных значений перечисления. В конструкторе я передаю тип, который следует тем же границам, что и параметр generi c. Я ожидаю, что проверка login_type === TwoChoices.REGISTER сузит тип класса generi c параметр T, однако этого не происходит. Вот пример.

enum TwoChoices {
    LOGIN,
    REGISTER
}

class ConditionalGenericClass<T extends TwoChoices> {
    password: string;
    email: string;
    username?: T extends TwoChoices.REGISTER ? string : never;
    constructor(login_type: T) {
        this.password = '';
        this.email = '';
        if (login_type === TwoChoices.REGISTER) {
            this.username = '';
        }
    }
}

Ссылка на игровую площадку Typescript

Приведенное выше выдает TypeError: Type '""' is not assignable to type '(T extends TwoChoices.REGISTER ? string : never) | undefined'..

То, что я ожидал чтобы иметь возможность писать, просто добавьте охранник типа с C extends TwoChoices.REGISTER в качестве возвращаемого типа функции, например:

enum TwoChoices {
    LOGIN,
    REGISTER
}

function typeGuardExtendsTwoChoicesRegister<C extends TwoChoices>
    (login_type: C): C extends TwoChoices.REGISTER 
{
    return login_type === TwoChoices.REGISTER;
}

class ConditionalGenericClass<T extends TwoChoices> {
    password: string;
    email: string;
    username?: T extends TwoChoices.REGISTER ? string : never;
    constructor(login_type: T) {
        this.password = '';
        this.email = '';
        if (typeGuardExtendsTwoChoicesRegister(login_type)) {
            this.username = '';
        }
    }
}

Ссылка на игровую площадку Typescript

Однако это Кажется, что X extends Y не является допустимым типом возвращаемого типа защиты.

Каков правильный, лучший способ статического ввода таких типов JavaScript динамического c типа сценария ios?

Вероятно, вы предложите использовать наследование классов следующим образом:

class LoginCredentials {
    password: string;
    email: string;
    constructor() {
        this.password = '';
        this.email = '';
    }
}

class RegisterCredentials extends LoginCredentials {
    username: string;
    constructor() {
        super();
        this.username = '';
    }
}

Ссылка на игровую площадку Typescript

Но, на мой взгляд, нужно изменить способ Я кодирую только для кодирования типов, похоже, не соответствует моему пониманию философии TypeScript, заключающейся в том, чтобы быть просто надмножеством JavaScript, к которому вы просто добавляете некоторую информацию для ввода, но вместо этого требуется, чтобы вы изменили способ кодирования JavaScript . Использование классов также удваивает количество строк при транспиляции до ≤ es5, особенно при использовании const enum s в первом блоке кода по сравнению с методом наследования классов.

...