#Record<SingleKey, string> & Record<TupleKey, string[]> doesn't work as I'd want it to - workarounds?

7 messages · Page 1 of 1 (latest)

lapis mantle
#

I think the following will be the most fitting solution

type Merged<SingleKeys extends string, TupleKeys extends string, valueType = string> = {
    [K in SingleKeys | TupleKeys]: K extends SingleKeys ? valueType : valueType[];
};

type Speech = {
    mySpeech: string
}; // Just for the example

const getSpeech = async (text: string): Promise<Speech> => {
    return new Promise(resolve => {
        resolve({ mySpeech: text })
    });
};

async function bulkGetSpeech<SingleKeys extends string, TupleKeys extends string>(
    texts: Merged<SingleKeys, TupleKeys>
): Promise<Merged<SingleKeys, TupleKeys, Speech>> {
    const keys = Object.keys(texts) as (keyof typeof texts)[];
    const promises = keys.map(key => {
        const value = texts[key];
        if (Array.isArray(value)) {
            const tupleKey = key as keyof TupleKeys;
            return Promise.all(value.map(text => getSpeech(text))).then(values => [tupleKey, values]);
        }
        const singleKey = key as keyof SingleKeys;
        return getSpeech(value).then(audio => [singleKey, audio]);
    });
    const results = await Promise.all(promises);
    return Object.fromEntries(results);
}

const texts: Merged<"a" | "b", "c"> = {
    a: "a",
    b: "b",
    c: ["c1", "c2"]
};

let speeches: Merged<"a" | "b", "c", Speech>;
bulkGetSpeech(texts).then(val => { speeches = val });
shy dragon
#

Tysm I will be trying this out 🙏

#

!resolved

#

thanks!!

shy dragon
#

!unresolved

#

One problem I'm having with this solution is that I need to assert all the keys in the construction of the input object

#

Which kinda removes the added convenience