2017-12-24 94 views
10

Próbuję napisać projekt JavaScript ze ścisłym typowaniem przepływu wszędzie. Mam również zależność od big-integer. Brak jest ustawionych adnotacji przepływu w flow-typed, a Google nie dostarcza niczego przydatnego na ten temat.Jak zadeklarować typy przepływu dla funkcji, która ma pola?

Podobnie jak wiele pakietów JavaScript, big-integer eksportuje jedną funkcję, która jest zwykle nazywana bigInt. Można to nazwać bezpośrednio, tak jak: bigInt(13), bigInt("134e134") itd., Która tworzy obiekty będące dużymi liczbami całkowitymi (postanowiłem nazwać typ wartości zwracanej przez tę funkcję "klasą" zwaną "BigInteger" w oparciu o dokumentacja - ale nie sądzę, że internals faktycznie używają klas, ponieważ uważam, że pakiet pojawił się przed ES6).

Działa to dobrze na wyjściu funkcji i mogę dołączyć metody do tej klasy i wszyscy jesteśmy dobrzy. Jednak samo urządzenie bigInt ma pewne metody, np. bigInt.lcm(123, 234). Jak mogę to udokumentować?

declare module "big-integer-types" { 
    declare class BigInteger { 
    add(addend: BigIntInput): BigInteger; 
    minus(subtractand: BigIntInput): BigInteger; 
    /* snip */ 
    } 
    declare type BigIntInput = number | string | BigInteger; 
    declare type BigIntFn = (void | number | string | BigInteger) => BigInteger; 
} 

declare module "big-integer" { 
    import type { BigIntFn } from "big-integer-types"; 
    declare export default BigIntFn 
} 

Działa to dobrze dla pól z wielkich liczb, na przykład do sprawdzania typu bigInt(12).plus("144e53"). Który jest świetny. Ale to nie obejmuje bigInt.lcm(134, 1551) i daje błąd przepływu.

Alternatywą jest zadeklarowanie, że eksport modułu big-integer ma postać typu, który ma określone powiązane funkcje. Na przykład:

declare module "big-integer-types" { 
    declare type BigIntegerStaticMethods { 
    lcm(a: BigIntInput, b: BigIntInput): BigInteger, 
    /* snip */ 
    } 

    declare type BigIntInput = number | string | BigInteger; 
} 

declare module "big-integer" { 
    import type BigIntegerStaticMethods from "big-integer-types"; 
    declare export default BigIntegerStaticMethods 
} 

To działa dla metod statycznych, ale nie wiem jak to powiedzieć „Typ” może być nazywa. Tak więc nie mam pojęcia, jak osiągnąć oba naraz.

Wydaje się to dziwne, ponieważ funkcja z polami jest dość powszechna w javascript, a dokumentacja dotycząca przepływu sugeruje, że dołożył wielu starań, aby system typów obsługiwał javascript , ponieważ jest używany. Więc sądzę, że istnieje składnia przepływu, aby to osiągnąć, po prostu nie mogłem zrozumieć, co to było i nie mogłem go znaleźć w dokumentach.

Odpowiedz

4

Można zadeklarować nienazwany funkcję statycznego w klasie:

declare type BigIntInput = number | string | BigInteger; 
declare class BigInteger { 
    add(addend: BigIntInput): BigInteger; 
    minus(subtractand: BigIntInput): BigInteger; 

    static lcm(a: BigIntInput, b: BigIntInput): BigInteger; 
    static (data?: BigIntInput): BigInteger; 
} 

BigInteger.lcm(1,2); 
BigInteger(4).add(5); 
+0

Nie jestem pewien, dlaczego ta odpowiedź przyciąga tak wielu upvotes. To nie działa. Nienazwana funkcja statyczna nie jest rozpoznawana przez przepływ i powoduje błąd przepływu. –

+0

Czy możesz wyjaśnić błąd? Ten kod nie zawodzi dla mnie w [Flow/Try] (https://flow.org/try/), również tego używamy w naszej bazie kodu dla takich sytuacji. – user3707125

Powiązane problemy