2017-01-22 15 views
5

Ben dokümantasyon sayfasından https://flowtype.org/docs/union-intersection-types.html#_İşlevler için kesişim türü, neden her ikisi de tür bildirimlerini kabul etmiyor?

Ve hatasız bu kod tipi kontrolleri örnek

/* @flow */ 
class Foo {} 
class Bar {} 
declare var f: ((x: Foo) => void) & ((x: Bar) => void); 
f(new Foo()); 

aldı.

Benim için sonuç hemen belli değil. başka bir örnek ile sayfanın üst kısmına yakın bir yerde gösterdiği gibi

:

/* @flow */ 
type I = {a: number} & {b: number}; 
var x: I = {a: 1, b: 2}; 
x = {a: 1, b: 2, c: "three"}; 

(terimi semantik kendisi akar) kesişme 2 (veya daha fazla) türleri bileşiğidir. Bunlardan temel olarak AND.

Peki, neden f(new Foo()); tip denetimi başarısız olmaz? new Foo() argümanı, Bar'un bir örneği değildir, bu yüzden geçmemelidir.

Neyi eksik?

biraz daha araştırmadan sonra UPD

Ben | ve & swapların anlamı sen declare var (type karşı veya yerinde yazarak) kullandığınızda bulduk. Yine de ilk başta neden olsa bile bir açıklama bulamıyorum.

cevap

2

Sorunu yanlış anlamış olabilirim, ancak bunu yazım denetimine beklerdim. new Foo() argümanı, Foo tipine sahiptir, bu nedenle uygulama fFoo => ... tipinde olduğu sürece uygulama tamamlanmalıdır. Öyle. (da tipinde Bar => ... vardır). Karşılaştırma için

, f tip (x: Foo & Bar) => void olsaydı, işler new Foo çünkü kesinlikle tip Foo ait iken, aynı zamanda tip Bar ait değildir, typecheck olmaz.

Başka bir karşılaştırma için, f türünde ((x: Foo) => void) | ((x: Bar) => void) varsa, işler değişmez. new Foo argümanı, Foo tipindedir ve f, Foo => void türüne sahip olsa da, bunun yerine Bar => void türüne sahip olabilir.

+0

Sadece şu belgeyi alıntılarım: "Bir kesişim türü, tüm giriş türleri için bir değer gerektirir:". Bu örnekte argüman, 'f (new Foo()); '((x: Bar) => void)' türünde olmadığı için bunu tatmin edemez. – zerkms

+0

Bir başka tartışmalı örnek: 'var' beyan ve' farklı davranır type' beyan: https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoAxjAhgZx2AMTjjAG8BfDbPMAISwCczKATAU00bbABcBPAA7cCYALxgAFBIAeALkLEAlGIB8YAG5wAli2UAySTPn0Gy0Ws07FAblSp1jMFjDyR4qAFcAduh5a4XjIuCnDKFKhYEl5sSERwEoo2QA – zerkms

+0

Hmm, oldukça takip etmiyorum: '(x: Bar) => void' türü 'f' için değil, f (new Foo())' dır. 'F' işlevinin' (x: Foo) => void' türünün yanı sıra '(x: Bar) => void' türünde olduğunu; bu şekilde, 'Foo' türünde bir argüman olarak adlandırmak iyidir. –

İlgili konular