#typescript
Вопрос:
Я хотел бы понять, возможно ли разрешить TypeScript автоматически выводить общий тип из конструктора класса таким образом, чтобы класс мог быть расширен дочерними классами, и каждый дочерний класс может иметь свой общий тип (в данном случае строковые литералы), который легко выводится из параметра конструктора.
Чтобы проиллюстрировать:
class BaseClasslt;T extends stringgt; { constructor(param1: number, ...param2: T[]) { console.log(param1); param2.map((param) =gt; console.log(param)); } // param uses values inferred from param2 public classMethod(param: T) { console.log(param); } }
Из приведенного выше фрагмента я могу выполнить что-то вроде приведенного ниже, где TypeScript может выполнять проверку типов для каждого строкового литерала.
const myClass = new BaseClass( 0, 'a', 'b', 'c' ); myClass.classMethod('a') // correct myClass.classMethod('x') // TypeScript highlights this with red wavy line, thus incorrect, and this is expected for the type checking
Приведенный ниже фрагмент кода не будет работать, так как универсальный тип должен быть определен в дочернем классе:
// BaseClass is flagged with "Generic type 'BaseClasslt;Tgt;' requires 1 type argument(s).(2314)" class ChildClass extends BaseClass { constructor() { super(1, 'x', 'y', 'z'); } } const childClass = new ChildClass(); // trying to achieve where TypeScript able to allow 'x', 'y' and 'z' but no other. childClass.classMethod('x') // shall be correct childClass.classMethod('invalid') // TypeScript shall flag this
Я попробовал несколько примеров первоначального преобразования универсального типа из базового класса в необязательный, например T extends string | void = void
, но допустил ошибку в дочернем классе.
class BaseClasslt;T extends string | void = voidgt; { ... } class ChildClass extends BaseClass { constructor() { // Flagged with "Argument of type 'string' is not assignable to parameter of type 'void'.ts(2345)" super(1, 'x', 'y', 'z'); } }
Я понимаю, почему в настоящее время универсальный тип имеет void
значение по умолчанию и ChildClass
явно не указывает, что универсальный тип T
является чем-то иным, кроме void. Чтобы это сработало, мне придется:
class ChildClass extends BaseClasslt;'x' | 'y' | 'z'gt; { constructor() { super(1, 'x', 'y', 'z'); } }
Как бы я мог сказать TypeScript, чтобы он автоматически выводил «x», » y » и » z » из super()
вызова ChildClass
конструктора, вместо того, чтобы явно указывать общий тип T
при расширении BaseClass
?