javascript - Promise.all זורק שגיאת סוג כאשר קוראים למספר פונקציות אסינכרוניות עם סוגי החזרה שונים


יש לי 3 סוגים:

export interface Animal {
...
}

export interface Cat extends Animal{
...
}

export interface Dog extends Animal{
...
}

export interface Iguana extends Animal {
...
}

בקובץ נפרד הגדרתי 3 פונקציות אסינכרוניות עם הסינטקס הבא:

const task1 = (() => Promise<Cat[]>) = async () => {
...
}

const task2 = (() => Promise<Dog[]>) = async () => {
...
}

const task3 = (() => Promise<Iguana[]>) = async () => {
...
}

const tasks = [task1, task2, task3];
const runningTasks = tasks.map(task => task());
// below line throws an error
const results = await Promise.all(runningTasks);

השורה האחרונה זורקת שגיאה בגלל אי-התאמת סוגים, והיא ארוכה מאוד ובבסיס אומרת "לכלב חסרות תכונות של חתול".

מה שאני מנסה לעשות הוא פשוט לקרוא לשלוש הפונקציות הללו באופן אסינכרוני ולשמור את התוצאות שלהן.

תשובה #1

מה שאני מנסה לעשות הוא פשוט לקרוא לשלוש הפונקציות הללו באופן אסינכרוני ולשמור את התוצאות שלהן.

יש לך את סוג ההגדרה הזה:

export interface Animal {
    name: string;
}

export interface Cat extends Animal {
    attitude: string;
}

export interface Dog extends Animal {
    sleepDuration: number;
}

export interface Iguana extends Animal {
    skinToughness: number;
}

const task1 = async (): Promise<Cat[]> => {
    return await Promise.resolve([]);
}

const task2 = async (): Promise<Dog[]> => {
    return await Promise.resolve([]);
}

const task3 = async (): Promise<Iguana[]> => {
    return await Promise.resolve([]);
}

גישה אחת היא להשתמש בסוג ההורה ב-Promise כך:

const demo = async () => {
    const tasks = [task1, task2, task3];
    const runningTasks: Promise<Animal[]>[] = tasks.map(task => task());
    const results: Animal[][] = await Promise.all(runningTasks);
}

אם חשוב להשתמש בסוגים הספציפיים מהתוצאות, הטופל שהציע jcalz יעבוד:

const demo = async () => {
    const tasks = [task1, task2, task3] as const;

    type TaskResults = [
        ReturnType<typeof task1>,
        ReturnType<typeof task2>,
        ReturnType<typeof task3>,
    ];

    const runningTasks = tasks.map(task => task()) as TaskResults;
    const results = await Promise.all(runningTasks);

    results[0][0].attitude;
    results[1][0].sleepDuration;
    results[2][0].skinToughness;
}

למפתיע, אם אינך צריך להתחיל את המשימות מראש, אז תוכל לשמור על מידע טיפוס עם הגישה הזו:

const demo = async () => {

    const results = await Promise.all([
        task1(),
        task2(),
        task3()
    ])

    results[0][0].attitude;
    results[1][0].sleepDuration;
    results[2][0].skinToughness;
}