Type annoteren reflectPromise methode

stemmen
0

Ik probeerde annoate typt u een versie van de reflectbelofte methode van hier - https://stackoverflow.com/a/31424853/1828637

function reflectPromise(p){
    return p.then(data => ({
                data,
                resolved: true
             }))
            .catch(error => ({
                error,
                rejected: true
             }));
}

Wat het doet is neemt een belofte, en geeft een andere belofte wanneer het wordt opgelost of afgewezen.

De dingen die ik probeer te maken met pseudocode:

  1. Verklaren dat dataistypeof ResolveValue(p)
  2. Verklaren dat erroristypeof RejectValue(p)
  3. Verklaren dat anderen kunnen testen const didReject = !!(await (reflectedPromise(somePromise)).rejected(wat dit voor opgelost beloften zal doen, die terugkeert { data: xxx, resolved:true }) is turn undefinedaan true. Op dit moment als ik dat doe !!blah.rejectedzegt Typescript mijProperty 'rejected' does not exist on type

Dit is wat ik heb tot nu toe:

function reflectPromise(p: Promise<any>): Promise<
        { data: any, resolved: boolean, rejected: void  } |
        { error: any, resolved: void, rejected: boolean }
    > {
    return p.then(data: any) => ({
                data,
                resolved: true
             }))
            .catch((error: any) => ({
                error,
                rejected: true
             }));
}
De vraag is gesteld op 19/09/2018 om 21:29
bron van user
In andere talen...                            


1 antwoorden

stemmen
2

U moet een algemeen type te gebruiken om het type van het resultaat afgeleid hebben. Het type van de fout wordt beschouwd anyin Typescript en er is geen soort veiligheid daar. Ook zou ik typ rejecteden resolvedals undefinedniet void(de waarde ervan zal worden undefined immers tijdens de uitvoering, dus het is meer acurate) en ik zou ze optioneel te maken wanneer ze niet aanwezig zijn.

Ook wanneer resolveen rejectzijn true, zou ik hen type als het boolean letterlijke soort true, zodat het type-bewakers om beter te werken.

Putting het samen, dit compileert (met strikte null controles):

function reflectPromise<T>(p: Promise<T>): Promise<
        { data: T, resolved: boolean, rejected?: undefined  } |
        { error: any, resolved?: undefined, rejected: boolean }
    > {
    return p.then((data: any) => ({
                data,
                resolved: true
            }))
            .catch((error: any) => ({
                error,
                rejected: true
            }));
}


(async function (somePromise: Promise<number>) {
    const result = await (reflectPromise(somePromise));
    const didReject = !!result.rejected
    if (result.rejected) {
        result.error // result is { error: any, resolved?: undefined, rejected: true }
    } else {
        result.data // result { data: number, resolved: true, rejected?: undefined  } 
    }

    if (result.resolved) {
        result.data // result { data: number, resolved: true, rejected?: undefined  } 
    } else {
        result.error // result is { error: any, resolved?: undefined, rejected: true }
    }
})(Promise.resolve(1));

Ook de uitvoering van de reflectPromiseziet er beter uit met async/awaitin mijn mening:

async function reflectPromise<T>(p: Promise<T>): Promise<
    { data: T, resolved: true, rejected?: undefined } |
    { error: any, resolved?: undefined, rejected: true }
> {
    try {
        return {
            data: await p,
            resolved: true
        }
    } catch (e) {
        return {
            error: e,
            rejected: true
        }
    }
}

Zonder strenge null controles, zal het type guard gedeeltelijk werken als we nodig hebben om de types te veranderen een beetje, en zet u beide resolveden rejectop beide takken:

async function reflectPromise<T>(p: Promise<T>): Promise<
    { data: T, resolved: true, rejected: false } |
    { error: any, resolved: false, rejected: true }
> {
    try {
        return {
            data: await p,
            resolved: true,
            rejected: false,
        }
    } catch (e) {
        return {
            error: e,
            rejected: true,
            resolved: false
        }
    }
}

(async function (somePromise: Promise<number>) {
    const result = await (reflectPromise(somePromise));
    const didReject = !!result.rejected
    if (result.rejected) {
        result.error // result is { error: any, resolved?: undefined, rejected: true }
    } 

    if (result.resolved) {
        result.data // result { data: number, resolved: true, rejected?: undefined  } 
    }
})(Promise.resolve(1));
antwoordde op 19/09/2018 om 22:41
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more