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

2024-06-26

想象一下这个类描述了一个由作为其属性之一的键引用的对象存储:

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:

interface Person {
    name: string;
    address: string;
}

interface Product {
    id: number;
    name: string;
    category: string;
}

const personStore = new Store<Person, 'name'>('name'); // Stores Persons indexable by their name
const productStore = new Store<Product, 'id'>('id'); // Stores Products indexable by their id

personStore.put({name: 'Homer Simpson', address: '742 Evergreen Terrace'})
const homer = personStore.get('Homer Simpson');

productStore.put({id: 42, name: 'Pizza', category: 'Food'});
const pizza = productStore.get(42);

这可行,但令我困扰的是在创作时,Store:s 必须声明用作键的属性两次 - 一次作为类型参数,一次作为文字值。 现在,可以从给定的参数值推断类型参数,但在这种情况下,T不是参数的一部分,因此必须将其声明为类型参数。K, 然而is构造函数参数的类型,以便可以推断它。但似乎无法推断K同时陈述T?

如果我完全省略类型参数,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. 

我考虑过声明一个构造函数接口,但这没有帮助。创建静态工厂方法可以返回完全类型化的通用对象,但也无法指定T从中推断 Kkey.

我显然也不想仅仅为了推断而在构造函数中提供虚拟项T.

So: 是否有可能在声明另一种泛型类型的同时从参数推断出另一种泛型类型?或者有一些聪明的解决方法吗?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript 构造函数,其中一种泛型类型是显式的,另一种是推断的 的相关文章

随机推荐