Дженерики TypeScript: расширение предоставленного интерфейса

#angular #typescript #rxjs

#angular #typescript #rxjs

Вопрос:

Я хочу использовать generics для службы Angular, чтобы люди могли передавать массив любого интерфейса / класса / типа, который они хотят, но я хочу, чтобы переданный тип расширял интерфейс, предоставляемый службой. Это сбивает с толку при написании, но вот как пока выглядит сервис:

 export interface ProvidedInterface {
  stepId: number;
  parentId: number;
}

@Injectable()
export class ManagerService {
  private myModelBs: BehaviorSubject<Array<Array<T extends ProvidedInterface>>> = new BehaviorSubject<Array<Array<T extends ProvidedInterface>>>(null);
  constructor() {}
}
  

Таким BehaviorSubject образом, будет содержать многомерный массив, где каждый элемент в массиве представляет собой массив универсального типа, который расширяет ProvidedInterface . К сожалению, это, похоже, не работает. VS Code подчеркнул T красными волнистыми линиями, сообщив, что не может найти имя «T», и первое > после Array объявления вложенного типа (их три подряд; первое из них — это то, что я имею в виду) также подчеркнуто и говорит «? ожидается».

Возможно, я делаю это неправильно, но я подумал, что для того, чтобы сделать эту службу многоразовой, я мог бы использовать дженерики, которые расширяют этот предоставленный интерфейс, и тогда служба не будет полагаться на какие-либо другие поля, кроме полей в предоставленном интерфейсе.

Надеюсь, это имеет смысл в том, что я пытаюсь сделать, но я не уверен, почему VS Code в первую очередь не нравится T generic; насколько я могу судить, это должно работать, по крайней мере, даже если остальные этого не делают.

Ответ №1:

Это то, что в итоге сработало для меня:

 export interface ProvidedInterface {
  stepId: number;
  parentId: number;
}

@Injectable()
export class ManagerService<T extends ProvidedInterface> {
  private myModelBs: BehaviorSubject<Array<Array<T>>> = new BehaviorSubject<Array<Array<T>>>(null);
    constructor() {}

}
  

Обратите внимание, что объявление типа теперь после имени службы, ManagerService . Затем в объявлении типа для BehaviorSubject все, что нужно для типа, — это T .