我正在尝试编写一个通用函数
钥匙与事物集合相匹配
其中值是返回不同类型 Promise 的函数,
到目前为止,我已经想出了以下内容,但我不知道如何正确输入返回类型。
// ---- Example Usage ----
type DataItem = { id1: string; id2: number; data: unknown };
type Type1 = { type1: string };
type Type2 = { type2: string };
const collection: DataItem[] = [
{ id1: 'asdfasdf', id2: 123123, data: 'blah' },
{ id1: 'zxcvzxcv', id2: 345675647, data: 'zing zang' },
];
loadReferencedRecords(collection, {
id1: () => Promise.resolve({ type1: 'asdfas' } as Type1),
id2: () => Promise.resolve({ type2: 'asdfas' } as Type2),
}).then(({
id1: type1sById, // <<< 😔 Wanting Type1, not both
id2: type2sById, // <<< 😔 Wanting Type2, not both
}) => {
const type1 = type1sById['asdfasdf']; // 😔 Wanting "Type1" but getting "Type 1 | Type 2"
});
// ---- Implementation ----
export async function loadReferencedRecords<
Item extends { [key: string ]: unknown },
Getters extends Partial<{ [key in keyof Item]: (id: string) => Promise<unknown> }>,
Key extends keyof Getters,
>(
items: Item[],
getters: Getters
): Promise<{
[key in Key]: Record<
string,
Exclude<Awaited<ReturnType<Exclude<
Getters[Key], // <<<< ????
undefined>>>,undefined>
>
}> {
return {}; //
}
您需要使用
key
(每个键的文字类型)而不是 Key
(键的联合类型):
// ---- Example Usage ----
type DataItem = { id1: string; id2: number; data: unknown };
type Type1 = { type1: string };
type Type2 = { type2: string };
const collection: DataItem[] = [
{ id1: 'asdfasdf', id2: 123123, data: 'blah' },
{ id1: 'zxcvzxcv', id2: 345675647, data: 'zing zang' },
];
loadReferencedRecords(collection, {
id1: () => Promise.resolve({ type1: 'asdfas' } as Type1),
id2: () => Promise.resolve({ type2: 'asdfas' } as Type2),
}).then(({
id1: type1sById, // <<< 😁 inferred: Type1
id2: type2sById, // <<< 😁 inferred: Type2
}) => {
const type1 = type1sById['asdfasdf']; // 😁 inferred: Type 1
});
// ---- Implementation ----
export async function loadReferencedRecords<
Item extends { [key: string ]: unknown },
Getters extends Partial<{ [key in keyof Item]: (id: string) => Promise<unknown> }>,
Key extends keyof Getters,
>(
items: Item[],
getters: Getters
): Promise<{
[key in Key]: Record<
string,
Exclude<Awaited<ReturnType<Exclude<
Getters[key], // << not Key
undefined>>>,undefined>
>
}> {
return {}; //
}