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.