TypeScript构造函数,其中一个泛型类型是显式的,一个是推断的

TypeScript构造函数,其中一个泛型类型是显式的,一个是推断的,typescript,typescript-generics,Typescript,Typescript Generics,假设该类描述一个键引用的对象存储,该键是其属性之一: class Store<T, K extends keyof T> { readonly key: K; readonly items: Map<T[K], T> = new Map(); constructor(key: K) { this.key = key; } put(item: T) { this.items.set(item[thi

假设该类描述一个键引用的对象存储,该键是其属性之一:

class Store<T, K extends keyof T> {
    readonly key: K;
    readonly items: Map<T[K], T> = new Map();

    constructor(key: K) {
        this.key = key;
    }

    put(item: T) {
        this.items.set(item[this.key], item);
    }

    get(key: T[K]): T | undefined {
      return this.items.get(key);
    }
}
这是可行的,但在创建时,
Store
:s必须两次声明用作键的属性,一次作为类型参数,一次作为文本值。 现在,可以从给定的参数值推断类型参数,但在本例中,
T
不是参数的一部分,因此必须将其声明为类型参数<但是,code>K是构造函数的参数类型,因此可以对其进行推断。但在陈述
t
时,似乎无法推断
K

如果我完全省略了类型参数,
T
将被推断为
never
,给出了一个无用的对象,并且在构造过程中出现了一个错误:

const someStore = new Store('name'); // Gives "argument of type name is not assignable to never"
我想要的是能够做到这一点:

const personStore = new Store<Person>('name'); // T is Person, name is keyof Person. 
const personStore=new Store('name');//T是人,名字是人的钥匙。
我考虑过声明一个构造函数接口,但那没有帮助。创建静态工厂方法可以返回一个完全类型的泛型对象,但也会遇到无法指定
T
而从
key
推断K的问题

显然,我也不想在构造函数中提供一个虚拟项,仅仅是为了推断
t

所以:在声明另一个泛型类型时,是否可以从参数中推断出一个泛型类型?还是有一些巧妙的解决方法?

界面人员{
名称:字符串;
地址:字符串;
}
接口产品{
id:编号;
名称:字符串;
类别:字符串;
}
班级商店{
只读键:keyof T;
只读项:Map=newmap();
构造函数(键:keyof T){
this.key=key;
}
付诸表决(项目:T){
this.items.set(item[this.key],item);
}
get(key:T[keyof T]):T |未定义{
返回此.items.get(键);
}
}
const personStore=new Store('name');//存储可按姓名索引的人员
const productStore=new Store('id');//存储可通过其id索引的产品
personStore.put({姓名:'Homer Simpson',地址:'742 Evergreen Terrace'})
const homer=personStore.get('homer Simpson');
productStore.put({id:42,名称:'Pizza',类别:'Food');
const pizza=productStore.get(42);
控制台日志(比萨饼)

不可能。。变通方法变通方法似乎是最好的选择,尽管它需要静态工厂方法。谢谢。这个答案可以简化为“你不需要通用的K,直接使用
keyof T
”。(这可能不太准确。)也许这是最好的解决方案,但您仍然有一个联合类型,
const pizza=productStore.get(42)该方法同时接受数字和字符串。是的,您拥有的权限不是完全严格的。但如果你知道更好的解决方案:)谢谢,但这根本不是一个解决方案。TBH我是这样开始的,然后意识到我也需要K(这个例子明显简化了,我的实际代码是一个更大的类,对T和K都有很多用处),所以这实际上是一个“我怎么做?”问题的“不要做”答案。这样,您在获取项目时就没有任何类型信息,正如@Silvermind所说的——如果项目包含字符串、数字和布尔值,您可以使用
string | number | boolean
作为键,这是非常无用的。
const personStore = new Store<Person>('name'); // T is Person, name is keyof Person.