2016-12-17 8 views
11

Uczę się Flow i dlatego pracuję nad małym projektem hobby z JavaScript i Flow. Mam klasę Foo i inną klasę Bar, którą chcę wziąć w tablicy obiektów Foo jako opcję w konstruktorze. Jednak chcę również móc wysyłać inne dane dla każdego takiego obiektu, dlatego chcę mieć tablicę, w której każdy element jest zwykłym obiektem Foo lub obiektem Foo zawiniętym w tablicę lub obiekt.Nie można przypisać tablicy obiektów do tablic typów związków w przepływie

Jednak gdy próbowałem napisać kod, otrzymałem kilka dziwnych błędów, których nie rozumiem. O ile mogę to stwierdzić, uważa się, że istnieje konflikt typów, ponieważ Foo nie jest kompatybilny z wszystkie typów związków, ale o ile rozumiem, powinien być zgodny tylko z co najmniej jednym z nich ...

Oto minimalny kod musiałem odtworzyć dokładne błędy dostałam (link to tryflow.org example):

// @flow 

class Foo { } 

interface BarOptions { 
    foos: (Foo | [ Foo ] | { foo: Foo })[];   // line 6 
} 

class Bar { 
    constructor(options?: BarOptions) { } 
} 

const foo: Foo = new Foo(); 

const bar = new Bar({ 
    foos: [ foo ],         // line 16 
}); 

otrzymuję następujące błędy:

Line 6: 
    tuple type: This type is incompatible with Foo 
    object type: This type is incompatible with Foo 
Line 16: 
    tuple type: This type is incompatible with Foo 
    object type: This type is incompatible with Foo 

Czy istnieje intuicyjny (lub nieintuicyjny) powód tych błędów?

Odpowiedz

2

Myślę, że w rzeczywistości BarOptions powinien być raczej aliasem typu zamiast interfejsu. Interfejs declares a type that classes can implement. Interfejsy nie są typami danych i nie powinny zawierać pól (zawierających dane).

Tutaj wszystko działa, jeśli zmienimy tylko interface BarOptions na type BarOptions =.

Alternatywnie można zmienić foo stać się funkcja pochłaniacza:

interface BarOptions { 
    foos(): (Foo | [ Foo ] | { foo: Foo })[]; 
} 
2

Myślisz, że może to być związane z tym otwartym Github ticket? Jeśli zamieniamy interface na type, to potwierdzi:

// @flow 

class Foo { } 

type BarOptions ={ 
    foos: 
     Class<Foo> | 
     Foo | 
     Foo[] | 
     { foo: Foo } 
} 

class Bar { 
    constructor(options?: BarOptions) { } 
} 

const foo: Foo = new Foo(); 

const bar = new Bar({ 
    foos: Foo, 
// foos: foo, 
// foos: [foo], 
// foos: { foo: foo }, 
}); 
+0

Czy możesz wyjaśnić, że to zadziała? (Moje pytanie nie dotyczy tego, jak to naprawić, najpierw próbuje zrozumieć, dlaczego to jest problem). – Frxstrem

+0

Nie widzę, jak te dwa są różne; jak już zrozumiałem, w obu przypadkach "foo" zostanie zadeklarowane z tym samym typem ('Foo'), jedyną różnicą jest to, że w pierwszym wierszu typ jest niejawny, podczas gdy w drugim jest jawny. O ile nie potwornie źle zrozumiałem, w jaki sposób działają typy przepływu, nie widzę, w jaki sposób zachowują się one inaczej (choć rzeczywiście tak się dzieje). – Frxstrem

+0

Czy ten problem może być związany z tym? https://github.com/facebook/flow/issues/1569 –

Powiązane problemy