我正在努力如何用TypeScript强类型化一些功能。TypeScript泛型
本质上,我有一个函数接受DataProviders的键/值映射,并返回从每个返回的数据的键/值映射。这里的问题的一个简化版本:
interface DataProvider<TData> {
getData(): TData;
}
interface DataProviders {
[name: string]: DataProvider<any>;
}
function getDataFromProviders<TDataProviders extends DataProviders>(
providers: TDataProviders): any {
const result = {};
for (const name of Object.getOwnPropertyNames(providers)) {
result[name] = providers[name].getData();
}
return result;
}
目前getDataFromProviders
有any
返回类型,但我想它,这样如果调用是这样的...
const values = getDataFromProviders({
ten: { getData:() => 10 },
greet: { getData:() => 'hi' }
});
...然后values
会隐式强类型为:
{
ten: number;
greet: string;
}
我想这将涉及与TDataProviders
b的泛型参数返回一个泛型类型我不能解决这个问题。
这是最好的我能想出但不编译...
type DataFromDataProvider<TDataProvider extends DataProvider<TData>> = TData;
type DataFromDataProviders<TDataProviders extends DataProviders> = {
[K in keyof TDataProviders]: DataFromDataProvider<TDataProviders[K]>;
}
我竭力想出,没有我在TData
明确地传递作为第二个参数编译一个DataFromDataProvider
类型,我认为我不能这样做。
任何帮助将不胜感激。
如果提供程序的数量是固定的并且相对较小(<= 10),则可以通过更改getDataFromProviders以使用可变参数,使用幻像类型对密钥进行编码(“ten”,“greet” )。许多样板,但它给你想要的:https://gist.github.com/evansb/7afc5ac7e640a06759276f456970e857 –
谢谢@EvanSebastian,这是一个有趣的方法。我不知道你可以写出'[K in K2]',其中K2不是数组。结果类型正是我想要的,但代码不起作用。这种方法失去了数据提供者的物理名称。我可以让每个提供者返回他们的名字,但我想保持干爽。 – CodeAndCats
哦,我只是复制粘贴你的代码,你需要明显修改它。我应该把实施留空,我的坏处。 是的,不幸的是,不可能让每个提供者返回它们的类型,并从中获得一个字符串文字类型。我相信你需要存在型 –