Как правильно реализовать интерфейс декоратора для перегруженного класса - PullRequest
0 голосов
/ 17 мая 2018

Я хочу расширить класс UserStore implements IUserStore с помощью декоратора, @asyncStore.IUserStore - это интерфейс, расширяющий IAsyncStore.Однако TypeScript жалуется на то, что я неправильно внедряю AsyncStore в классе UserStore.

Полная ошибка:

TS2420: Class 'UserStore' incorrectly implements interface 'IUserStore'.
Property 'isLoading' is missing in type 'UserStore'

Как правильно все набрать, чтобы мой UserStore правильно напечатан?

Вот некоторые фрагменты моего кода (пропущен нерелевантный код и оставлены интерфейсы пустыми, если они не связаны с этой проблемой или ошибкой):

// Types
interface IAsyncStore {
  isLoading: boolean;
}

interface IUserStore extends IAsyncStore {}

// AsyncStore.ts
function asyncStore(constructor): any {
  class AsyncStore extends constructor implements IAsyncStore {
    private loading: boolean = false;

    public get isLoading(): boolean {
      return this.loading;
    }
  }

  return AsyncStore
}

// UserStore.ts
@asyncStore
class UserStore implements IUserStore {} // Error TS2420: ...

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

После дальнейшего поиска в Google похоже, что это еще не поддерживается TypeScript. Есть немного, но немного грязный обходной путь, чтобы заставить печатать работать.

Я добавил этот класс в свой код:

class DecoratorService implements IAsyncStore {
  isLoading: boolean;
}

И затем я использую этот класс в качестве базового для UserStore, например:

class UserStore extends DecoratorService implements IUserStore {}

TypeScript больше не выдает ошибку в моем коде, и я могу запустить его без каких-либо ошибок. Когда я хочу добавить другой декоратор, я просто добавляю необходимые значения в класс DecoratorService, и TypeScript поймет код.

0 голосов
/ 17 мая 2018

Мутация декоратора класса не поддерживается в TypeScript.

Класс должен быть дополнительно набран с объединенным интерфейсом, чтобы сделать добавленные свойства видимыми для системы ввода:

interface UserStore extends IUserStore {}
@asyncStore
class UserStore /* implements IUserStore */ {...}

Это противоречит цели использования декораторов для более сжатого кода.

implements IUserStore является избыточным, поскольку гарантируется объединенным интерфейсом UserStore, что класс UserStore уже реализует его.

Кроме того, IUserStore не служит хорошей цели, так как он аналогичен интерфейсу UserStore.

В этом случае прямое наследование способно обеспечить более беспроблемную и согласованную типизацию из-за ограничений TypeScript.

...