Допустим, у меня есть класс с параметром 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 в первом блоке кода по сравнению с методом наследования классов.