英文:
How to make a generic type an union type of Record<K,V> and an interface in Typescript?
问题
I want to declare a couple singleton class (Angular service) that must have some members named after an enum. Until now I had it as a 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'
  }
}
If I add a new RewardId Typescript lets me know that I have to implement it on MyConst this is what I want

[Typescript Playground link][2]
Now, I want to change it to a service (so a class) because it is easier to test and I also need some methods there.
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]
As the final step, I need this to convert that class definition into a generic interface:
This does not work interface Vault<K, V> extends VaultMethods, Record<K, V> because An interface can only extend an object type or intersection of object types with statically known members.
If I make it a type it kind of works in the way that TypeScript asks me to implement the methods and members
type Vault<K, V> = Record<K, V> & VaultMethods;
class MyClass2 implements Vault<RewardId, RewardObject> {
  
}
But It shows an error in the Type Definition:

Is there a way to fix this?
英文:
I want to declare a couple singleton class (Angular service) that must have some members named after an enum. Until now I had it as a 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'
  }
}
If I add a new RewardId Typescript lets me know that I have to implement it on MyConst this is what I want

[Typescript Playground link][2]
Now, I want to change it to a service (so a class) because it is easier to test and I also need some methods there.
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]
As final step I need this to convert that class definition in a generic interface:
This does not work interface Vault<K, V> extends VaultMethods, Record<K, V> because An interface can only extend an object type or intersection of object types with statically known members.
If I make it a type it kind of works in the way that Typescript ask me to implement the methods and members
type Vault<K, V> = Record<K, V> & VaultMethods;
class MyClass2 implements Vault<RewardId, RewardObject> {
  
}
But It shows an error in the Type Definition:

Is there a way to fix this?
答案1
得分: 4
It seems that you were missing a constraint on type parameter K. Since you're passing it to Record and that the K is probably an enum, you can say that K extends string.
type Vault<K extends string, V> = Record<K, V> & VaultMethods;
<details>
<summary>英文:</summary>
It seems that you were missing a constraint on type parameter `K`. Since you're passing it to `Record` and that the K is probably an enum, you can say that `K` extends `string`.
type Vault<K extends string, V> = Record<K, V> & VaultMethods;
[typescript playground][1]
  [1]: https://www.typescriptlang.org/play/?ssl=17&ssc=28&pln=17&pc=13#code/KYOwrgtgBASsDuBDATgEwJKqgbwLACgooAJAUTKgF4oByAQVQFkB7AIziTUzLJoBoCRYgHkRVWgxbsEKDKhEj%20gqAHoVxOhvH0mbDrO6a6S-AF8CBAJYgALsGQAzRAGNgsGWmGsAVsGc2cZUtUAC53TjkAbmUAZ2YIYAARRBtEMMQQAE8Cc3wrW3snVygANUQwABsbRmAbAAtmVBjAwiI4hJr6xoBGAAoASjCAN2Zg6Nb24E6G1AAmAeHR1HHcghtMgAc3MsqbAB4AaShgAA87ECaoGJtkawBzPlKAPnE4Z2Y0Q8eSl4AyUvKVWmjRi4wIzgqiBizUYmQAwpDoVBLBANhVgAlbM0dlU9vouKhHvjUF5fP4XnhWgBtYmYAB0PFIAF1xJSiERgmFaagGeRSAJWm14kkUmlaJNkqkaMpTGDqdyGaJhCzqGz2ZzwgYeQphAL2VdhZKxTQJaLpa1ZRYJsLgag%20v0cFBVtaOrUZvMHdgnTkCEA
</details>
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论