Как сделать обобщенный тип c объединяющим типом Record а интерфейс в Typescript? - PullRequest
0 голосов
/ 06 января 2020

Я хочу объявить пару одноэлементных классов (Angular service), которые должны иметь несколько членов, названных в честь перечисления. До сих пор у меня было это как const:

enum RewardId {
  HEHE = 'AdMobRewardIdHEHE',
  HOHO = 'AdMobRewardIdHOHO',
}

interface RewardObject {
  id: RewardId;
  someData: any
}


const MyConst: Record<RewardId, RewardObject> = {
  [RewardId.HEHE]: {
    id: RewardId.HEHE,
    someData: 'someData'
  },

  [RewardId.HOHO]: {
    id: RewardId.HOHO,
    someData: 'someData'
  }
}

Если я добавлю новый RewardId Typescript, я узнаю, что мне нужно реализовать его на MyConst , это то, что я хочу

enter image description here [Typescript Playground link] [2]

Теперь я хочу поменять его на сервис (то есть класс), потому что его легче и мне также нужны некоторые методы.

interface VaultMethods {
   someMethod1(): void;
  someMethod2(): void;
}

class MyClass implements Record<RewardId, RewardObject>, VaultMethods {
  [RewardId.HEHE] = {
    id: RewardId.HEHE,
    someData: 'someData'
  };

  [RewardId.HOHO] = {
    id: RewardId.HOHO,
    someData: 'someData'
  };

  someMethod1() { }

  someMethod2() { }
}

[Typescript Playground] [3]

В качестве последнего шага мне нужно преобразовать это определение класса в обобщенном c интерфейсе:

Это не работает interface Vault<K, V> extends VaultMethods, Record<K, V>, потому что An interface can only extend an object type or intersection of object types with statically known members.

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

type Vault<K, V> = Record<K, V> & VaultMethods;
class MyClass2 implements Vault<RewardId, RewardObject> {

}

Площадка для машинописи as type

Но в определении типа отображается ошибка: error in the Type Definition

Есть ли способ это исправить?

1 Ответ

2 голосов
/ 06 января 2020

Похоже, вы пропустили ограничение на параметр типа K. Поскольку вы передаете его в Record и что K, вероятно, является перечислением, вы можете сказать, что K расширяет string.

type Vault<K extends string, V> = Record<K, V> & VaultMethods;

машинопись игровая площадка

...