Typescript: Общий тип в базовом классе - PullRequest
0 голосов
/ 30 января 2019

У меня в качестве сокращенного примера приведен следующий код:

class QueryArgs {
  studentId?: string;
  teacherId?: string;
}

class BaseValidator<T> {
  protected args: T;

  constructor(args: T) {
    this.args = args;
  }

  protected requireTeacher(): void {
    if (!this.args.teacherId) {
      throw new Error("teacherId required");
    }
  }
}

class QueryValidator extends BaseValidator<QueryArgs> {
  public validateAdmin(): QueryArgs {
    this.requireTeacher();
    return this.args;
  }
}

// Recreated implementation from a third party library
const args: QueryArgs = new QueryArgs();
args.studentId = "XXXX-XXX-XXX";

// Not the actual implementation just for illustration
const validator = new QueryValidator(args);
const validArgs = validator.validateAdmin();

Проблема, с которой я столкнулся, заключается в классе BaseValidator в методе requireTeacher this.args.teacherId с ошибкой Property 'teacherId' does not exist on type 'T'.

Я не уверен, чего мне не хватает в обобщенной части Typescript.

В идеале TS должен знать в BaseValidator, что args является экземпляром QueryArgs.

Заранее спасибо!

1 Ответ

0 голосов
/ 30 января 2019

Необходимо дополнительно ограничить аргумент универсального типа T типом, обладающим свойством teacherId.Таким образом, любой тип может быть передан как T, что означает, что вы не можете предполагать, что T имеет teacherId.

Чтобы ограничить тип, попробуйте изменить class BaseValidator<T> на class BaseValidator<T extends QueryArgs>.Это ограничивает T типами, которые расширяют QueryArgs, так что вы гарантировано, что T имеет свойство teacherId.

Ознакомьтесь с этой статьей, где упоминается ограничение общих аргументов с помощью extends:https://www.typescriptlang.org/docs/handbook/generics.html

...