typescript 如何根据输入类型严格且通用地键入返回对象

问题描述 投票:0回答:1

我正在尝试编写一个通用函数

  • 收集一些东西,
  • 拿一个物体
    • 钥匙与事物集合相匹配

    • 其中值是返回不同类型 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 {}; // 
}
typescript typescript-generics
1个回答
0
投票

您需要使用

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 {}; // 
}
© www.soinside.com 2019 - 2024. All rights reserved.