En mecanografiado, cómo definir el tipo de función asíncrona

84

Intenté definir un tipo de función asíncrona, pero fallé en la compilación, ver a continuación:

interface SearchFn {
    async (subString: string): string;
}

class A {
    private Fn: SearchFn
    public async do():Promise<string> {
        await this.Fn("fds") // complain here: cannot invoke an expression whose type lacks a call signature
        return ''
    }
}

¿Alguien puede ayudarme a resolver esto?

Ron
fuente
¿La promesa <boolean> no funciona?
toskv
Muestre cómo / dónde está definiendo Fn.

Respuestas:

156

Encontré esto buscando cómo declarar un "typedef" para una función de flecha asíncrona.

Funciona si simplemente declara el tipo de retorno de la función como una Promesa:

interface SearchFn {
    (subString: string): Promise<boolean>;
}

o como una declaración de tipo:

type SearchFn = (subString: string) => Promise<boolean>;

TS Linter de Microsoft recomendará esta segunda sintaxis.

Thiago Barcala
fuente
3
Inteligente, gracias, async func en realidad es una función de Promesa devuelta.
Ron
@Ron vale la pena mencionar que eso no es correcto, la función asincrónica simplemente usa await. Vea la respuesta de Motti
Code Noviciate
Las personas deben tener en cuenta que una función que devuelve una promesa no es necesariamente una función asíncrona.
liaguridio
1
¿Qué pasa si no hay valor devuelto? ): Promise<undefined>me está fallando. Solo necesito una función asincrónica para poder usarla awaitdentro ...
dcsan
2
@dcsan Promise <void>
Thiago Barcala
21

La asyncpalabra clave se usa para indicar al compilador / tiempo de ejecución que la función en cuestión usará awaitinternamente (para que pueda poner el andamiaje requerido para habilitarla ).

Esto significa que asyncsolo tiene significado para la implementación de la función, no su interfaz . Por lo tanto, tener asyncun método de interfaz no es útil, quiere decir que la función devuelve un cierto Promise(en su caso Promise<string>) pero no quiere exigir que el implementador de la interfaz lo implemente de cierta manera (usando await).

Entonces, como otros dijeron antes que yo:

interface SearchFn {
    (subString: string): Promise<string>;
}

Entonces, quien decida implementar esta función puede optar por utilizar una metodología asyncantigua Promise.theno tal vez incluso alguna nueva que surgirá en el futuro.

Motti
fuente
1
Gran respuesta y explica el "por qué" de manera sucinta.
Code Noviciado
7

Pase el tipo de objeto devuelto al genérico Promise.

type SearchFn = (subString: string): Promise<string>;

Alternativamente, puede declarar un AsyncFunctiontipo genérico.

type AsyncFunction <A,O> = (...args:A) => Promise<O> 
type SearchFn = AsyncFunction<[string], string>

AsyncFunction es un tipo genérico que recibe dos variables de tipo: el tipo de entrada (A) y el tipo de salida.

Ben Carp
fuente