Tipo de método de anotación reflectPromise

votos
0

Yo estaba tratando de escribir annoate una versión del reflectmétodo de la promesa de aquí - https://stackoverflow.com/a/31424853/1828637

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

Lo que hace es toma una promesa, y devuelve otra promesa cuando se resuelva o se rechaza.

Las cosas que estoy tratando de hacer con pseudocódigo:

  1. Declaran que dataestypeof ResolveValue(p)
  2. Declaran que errorestypeof RejectValue(p)
  3. Declaran que otros pueden probar const didReject = !!(await (reflectedPromise(somePromise)).rejected(lo que esto hará promesas para resolver, que devuelve { data: xxx, resolved:true }) se gire undefineda true. Actualmente cuando lo haga !!blah.rejectedmecanografiado me dice:Property 'rejected' does not exist on type

Esto es lo que tengo hasta el momento:

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
             }));
}
Publicado el 19/09/2018 a las 21:29
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
2

Es necesario utilizar un tipo genérico para tener el tipo del resultado deducido. El tipo de error se considera anya máquina y no hay seguridad de tipos allí. También tendría que escribir rejectedy resolvedque undefinedno void(su valor será indefinido después de todo en tiempo de ejecución por lo que es más acertadas) y yo les haría opcional cuando no están presentes.

También cuando resolvey rejectson true, yo escribo como el tipo literal booleano truecon el fin de permitir que tipo guardias para trabajar mejor.

Poniendo juntos, esto compila (con estrictos controles nulo):

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));

También la implementación de reflectPromiseapariencia mejor con async/awaiten mi opinión:

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
        }
    }
}

Sin estrictos controles nulos, el tipo de protección funcionará parcialmente si necesitamos cambiar los tipos un poco, y establece tanto resolvedy rejecten ambas ramas:

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));
Respondida el 19/09/2018 a las 22:41
fuente por usuario

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