Можно ли ограничить универсальные классы для конкретных методов?
Допустим, я создаю контейнер в TypeScript. Это может быть любой контейнер, но я буду использовать следующий простой пример:
class Container<T> {
val: T;
constructor(t: T) {
this.val = t;
}
}
Скажем, я хотел бы предложить функцию, чтобы, если у меня было два контейнера с числами, я мог легко создать новый контейнер с этими числами, сложенными вместе.
class Container<T> {
val: T;
constructor(t: T) {
this.val = t;
}
add(c: Container<number>): Container<number> {
return new Container(this.val + c.val);
}
}
Однако я не могу понять, можно ли выполнить приведенную выше проверку типов кода. Проблема в том, что все, что я знаю о this.val
это то, что это типа T
(что ничего). Я хотел бы как-то ограничить add
метод, так что он может быть вызван только в случаях Container<T>
где T == number
, Это возможно в TypeScript?
Вышесказанное является лишь надуманным примером. На самом деле я хочу создать интерфейс TypeScript для аппликативных функторов. Аппликативная функция имеет метод, который для Container
будет выглядеть так:
ap<A, B>(c: Container<A>): Container<B> {
return new Container(this.val(c.val));
}
Так что в этом случае я должен был бы знать, что T == (a: A) => B
, В целом, я хотел бы иметь возможность определить этот интерфейс:
interface Applicative<T> {
...
ap: <A, B>(a: Applicative<A>) => Applicative<B> // where T == (a: A) => B
...
}
Возможно ли это?
2 ответа
Вы не можете иметь ограничение для T, которое применяется к одному методу. Вы можете иметь их только на уровне класса.
Вы можете добавить ограничения к универсальным типам.
В вашем случае вы можете сделать что-то вроде этого:
interface HasNumber {
x: number;
}
class Container<T extends HasNumber> {
}
Но вы не можете иметь ограничения, используя основные типы, такие как число, строка, Bool...