2016-02-02 13 views
6

È possibile definire manualmente metodi aggiuntivi per una classe esistente?Flowtype: classi dinamicamente estese

mio caso d'uso specifico è di Bluebird promisifyAll() cui:

Promisifies l'intero oggetto passando attraverso le proprietà dell'oggetto e la creazione di un equivalente asincrona di ciascuna funzione sull'oggetto e la sua catena di prototipi ... http://bluebirdjs.com/docs/api/promise.promisifyall.html

Ovviamente, il flusso non sarebbe in grado di capirlo automaticamente. Quindi, sono disposto ad aiutarlo. La domanda è COME?

Si consideri il seguente codice

import http from 'http' 
import { promisifyAll } from 'bluebird' 

promisifyAll(http) 

const server = http.createServer(() => { console.log('request is in'); }) 
server.listenAsync(8080).then(() => { 
    console.log('Server is ready to handle connections') 
}) 

flusso dà il seguente errore qui:

property `listenAsync`. Property not found in 
Server 

non ci sarebbe alcun errore se ho usato listen. il flusso è abbastanza intelligente da vedere che questo è un vero metodo definito in un modulo. Ma è un'aggiunta dinamica da promisifyAll ed è invisibile per il flusso

risposta

7

Questo non è possibile e non sarebbe molto sicuro. Qui è qualcosa che si può fare per il vostro caso:

prima dichiarare bluebird come segue:

declare module "bluebird" { 
    declare function promisifyAll(arg: any): any 
} 

poi fare questo:

import httpNode from 'http' 
import { promisifyAll } from 'bluebird' 
import type { Server } from 'http' 


type PromisifiedServer = Server & { 
    listenAsync(port: number, hostname?: string, backlog?: number): Promise<PromisifiedServer>; 
}; 

type PromisifiedHttp = { 
    createServer(listener: Function): PromisifiedServer; 
}; 

const http: PromisifiedHttp = promisifyAll(httpNode) 

Qui gettiamo manualmente http digitare PromisifiedHttp. Dobbiamo ancora dichiarare manualmente tutti i tipi promisi, sebbene possiamo usare l'intersezione di tipo per estendere i tipi esistenti.

+0

grazie. questo non è perfetto, in quanto richiede il cambio di codice. piccolo cambiamento, ma ancora. e significa che il codice dovrebbe essere modificato anche per altri casi dinamici. Capisco che la parte "non sarebbe davvero sicura", ma non è realistica in quanto in entrambi i casi il compilatore non può dedurre i dati dal codice e si fida di me per scrivere la definizione corretta. – JimiDini

+0

in generale non è possibile esprimere alcuni modelli dinamici nel flusso. Devi isolare parti troppo dinamiche dal flusso e fornire dichiarazioni appropriate per le parti digitate – vkurchatkin

+0

Ridurrebbe drasticamente la curva se il flusso avesse un meccanismo per fare cose come l'estensione del prototipo in un modo "non sicuro". Ad esempio, se uso una libreria come should.js o chai, dovrei essere in grado di creare un'interfaccia in libs che estenda il prototipo di Object con la funzione 'should'. Se ciò non può essere fatto in un modo sicuro, consentire al consumatore di disabilitare l'analisi statica su quei percorsi di codice che lo utilizzano invece di generare errori. – cchamberlain

Problemi correlati