Sometimes it is useful to create a type which is all of a set of other
types. For example, you might want to write a function which accepts an object
which is the combination of other object types. For this, Flow supports
intersection types.
Grande Kors Poche Cartable 908327 Bleu Michael Zippée Sac Homme Marine xrCedQBoW
Cannot call `method` with object literal bound to `value` because property `b` is missing in object literal [1] but exists in `B` [2].
Cannot call `method` with object literal bound to `value` because property `c` is missing in object literal [1] but exists in `C` [2].
Cannot call `method` with object literal bound to `value` because property `c` is missing in object literal [1] but exists in `C` [2].
{"value":"// @flow\ntype A = { a: number };\ntype B = { b: boolean };\ntype C = { c: string };\n\nfunction method(value: A & B & C) {\n // ...\n}\n\n// $ExpectError\nmethod({ a: 1 }); // Error!\n// $ExpectError\nmethod({ a: 1, b: true }); // Error!\nmethod({ a: 1, b: true, c: 'three' }); // Works!\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"A","line":2,"start":14,"end":15},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":16,"end":17},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":18,"end":19},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":2,"start":20,"end":21},{"type":"T_COLON","context":"type","value":":","line":2,"start":21,"end":22},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":23,"end":29},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":30,"end":31},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":31,"end":32},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"B","line":3,"start":38,"end":39},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":40,"end":41},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":42,"end":43},{"type":"T_IDENTIFIER","context":"normal","value":"b","line":3,"start":44,"end":45},{"type":"T_COLON","context":"type","value":":","line":3,"start":45,"end":46},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":47,"end":54},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":55,"end":56},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":56,"end":57},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":58,"end":62},{"type":"T_IDENTIFIER","context":"type","value":"C","line":4,"start":63,"end":64},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":65,"end":66},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":67,"end":68},{"type":"T_IDENTIFIER","context":"normal","value":"c","line":4,"start":69,"end":70},{"type":"T_COLON","context":"type","value":":","line":4,"start":70,"end":71},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":72,"end":78},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":79,"end":80},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":80,"end":81},{"type":"T_FUNCTION","context":"normal","value":"function","line":6,"start":83,"end":91},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":6,"start":92,"end":98},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":98,"end":99},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":6,"start":99,"end":104},{"type":"T_COLON","context":"type","value":":","line":6,"start":104,"end":105},{"type":"T_IDENTIFIER","context":"type","value":"A","line":6,"start":106,"end":107},{"type":"T_BIT_AND","context":"type","value":"&","line":6,"start":108,"end":109},{"type":"T_IDENTIFIER","context":"type","value":"B","line":6,"start":110,"end":111},{"type":"T_BIT_AND","context":"type","value":"&","line":6,"start":112,"end":113},{"type":"T_IDENTIFIER","context":"type","value":"C","line":6,"start":114,"end":115},{"type":"T_RPAREN","context":"normal","value":")","line":6,"start":115,"end":116},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":117,"end":118},{"type":"Line","context":"comment","value":"// ...","line":7,"start":121,"end":127},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":128,"end":129},{"type":"Line","context":"comment","value":"// $ExpectError","line":10,"start":131,"end":146},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":11,"start":147,"end":153},{"type":"T_LPAREN","context":"normal","value":"(","line":11,"start":153,"end":154},{"type":"T_LCURLY","context":"normal","value":"{","line":11,"start":154,"end":155},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":11,"start":156,"end":157},{"type":"T_COLON","context":"normal","value":":","line":11,"start":157,"end":158},{"type":"T_NUMBER","context":"normal","value":"1","line":11,"start":159,"end":160},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":161,"end":162},{"type":"T_RPAREN","context":"normal","value":")","line":11,"start":162,"end":163},{"type":"T_SEMICOLON","context":"normal","value":";","line":11,"start":163,"end":164},{"type":"Line","context":"comment","value":"// Error!","line":11,"start":165,"end":174},{"type":"Line","context":"comment","value":"// $ExpectError","line":12,"start":175,"end":190},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":13,"start":191,"end":197},{"type":"T_LPAREN","context":"normal","value":"(","line":13,"start":197,"end":198},{"type":"T_LCURLY","context":"normal","value":"{","line":13,"start":198,"end":199},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":13,"start":200,"end":201},{"type":"T_COLON","context":"normal","value":":","line":13,"start":201,"end":202},{"type":"T_NUMBER","context":"normal","value":"1","line":13,"start":203,"end":204},{"type":"T_COMMA","context":"normal","value":",","line":13,"start":204,"end":205},{"type":"T_IDENTIFIER","context":"normal","value":"b","line":13,"start":206,"end":207},{"type":"T_COLON","context":"normal","value":":","line":13,"start":207,"end":208},{"type":"T_TRUE","context":"normal","value":"true","line":13,"start":209,"end":213},{"type":"T_RCURLY","context":"normal","value":"}","line":13,"start":214,"end":215},{"type":"T_RPAREN","context":"normal","value":")","line":13,"start":215,"end":216},{"type":"T_SEMICOLON","context":"normal","value":";","line":13,"start":216,"end":217},{"type":"Line","context":"comment","value":"// Error!","line":13,"start":218,"end":227},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":14,"start":228,"end":234},{"type":"T_LPAREN","context":"normal","value":"(","line":14,"start":234,"end":235},{"type":"T_LCURLY","context":"normal","value":"{","line":14,"start":235,"end":236},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":14,"start":237,"end":238},{"type":"T_COLON","context":"normal","value":":","line":14,"start":238,"end":239},{"type":"T_NUMBER","context":"normal","value":"1","line":14,"start":240,"end":241},{"type":"T_COMMA","context":"normal","value":",","line":14,"start":241,"end":242},{"type":"T_IDENTIFIER","context":"normal","value":"b","line":14,"start":243,"end":244},{"type":"T_COLON","context":"normal","value":":","line":14,"start":244,"end":245},{"type":"T_TRUE","context":"normal","value":"true","line":14,"start":246,"end":250},{"type":"T_COMMA","context":"normal","value":",","line":14,"start":250,"end":251},{"type":"T_IDENTIFIER","context":"normal","value":"c","line":14,"start":252,"end":253},{"type":"T_COLON","context":"normal","value":":","line":14,"start":253,"end":254},{"type":"T_STRING","context":"normal","value":"'three'","line":14,"start":255,"end":262},{"type":"T_RCURLY","context":"normal","value":"}","line":14,"start":263,"end":264},{"type":"T_RPAREN","context":"normal","value":")","line":14,"start":264,"end":265},{"type":"T_SEMICOLON","context":"normal","value":";","line":14,"start":265,"end":266},{"type":"Line","context":"comment","value":"// Works!","line":14,"start":267,"end":276}],"errors":[{"id":"E1","messages":[{"id":"E1M1","description":"Cannot call `method` with object literal bound to `value` because property `b` is missing in object literal [1] but exists in `B` [2].","context":"method({ a: 1 }); // Error!","source":"-","start":{"line":11,"column":8,"offset":154},"end":{"line":11,"column":15,"offset":162}}],"operation":null},{"id":"E2","messages":[{"id":"E2M1","description":"Cannot call `method` with object literal bound to `value` because property `c` is missing in object literal [1] but exists in `C` [2].","context":"method({ a: 1 }); // Error!","source":"-","start":{"line":11,"column":8,"offset":154},"end":{"line":11,"column":15,"offset":162}}],"operation":null},{"id":"E3","messages":[{"id":"E3M1","description":"Cannot call `method` with object literal bound to `value` because property `c` is missing in object literal [1] but exists in `C` [2].","context":"method({ a: 1, b: true }); // Error!","source":"-","start":{"line":13,"column":8,"offset":198},"end":{"line":13,"column":24,"offset":215}}],"operation":null}]}
Intersection type syntax
Intersection types are any number of types which are joined by an ampersand &
.
{"value":"Type1 & Type2 & ... & TypeN\n","tokens":[{"type":"T_IDENTIFIER","context":"normal","value":"Type1","line":1,"start":0,"end":5},{"type":"T_BIT_AND","context":"normal","value":"&","line":1,"start":6,"end":7},{"type":"T_IDENTIFIER","context":"normal","value":"Type2","line":1,"start":8,"end":13},{"type":"T_BIT_AND","context":"normal","value":"&","line":1,"start":14,"end":15},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":1,"start":16,"end":19},{"type":"T_BIT_AND","context":"normal","value":"&","line":1,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"normal","value":"TypeN","line":1,"start":22,"end":27}],"errors":[]}
You may also add a leading ampersand which is useful when breaking intersection
types onto multiple lines.
{"value":"type Foo =\n & Type1\n & Type2\n & ...\n & TypeN\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Foo","line":1,"start":5,"end":8},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":9,"end":10},{"type":"T_BIT_AND","context":"type","value":"&","line":2,"start":13,"end":14},{"type":"T_IDENTIFIER","context":"type","value":"Type1","line":2,"start":15,"end":20},{"type":"T_BIT_AND","context":"type","value":"&","line":3,"start":23,"end":24},{"type":"T_IDENTIFIER","context":"type","value":"Type2","line":3,"start":25,"end":30},{"type":"T_BIT_AND","context":"type","value":"&","line":4,"start":33,"end":34},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":4,"start":35,"end":38},{"type":"T_BIT_AND","context":"normal","value":"&","line":5,"start":41,"end":42},{"type":"T_IDENTIFIER","context":"normal","value":"TypeN","line":5,"start":43,"end":48}],"errors":[]}
Each of the members of a intersection type can be any type, even another
intersection type.
{"value":"type Foo = Type1 & Type2;\ntype Bar = Type3 & Type4;\n\ntype Baz = Foo & Bar;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Foo","line":1,"start":5,"end":8},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":9,"end":10},{"type":"T_IDENTIFIER","context":"type","value":"Type1","line":1,"start":11,"end":16},{"type":"T_BIT_AND","context":"type","value":"&","line":1,"start":17,"end":18},{"type":"T_IDENTIFIER","context":"type","value":"Type2","line":1,"start":19,"end":24},{"type":"T_SEMICOLON","context":"type","value":";","line":1,"start":24,"end":25},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":26,"end":30},{"type":"T_IDENTIFIER","context":"type","value":"Bar","line":2,"start":31,"end":34},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":35,"end":36},{"type":"T_IDENTIFIER","context":"type","value":"Type3","line":2,"start":37,"end":42},{"type":"T_BIT_AND","context":"type","value":"&","line":2,"start":43,"end":44},{"type":"T_IDENTIFIER","context":"type","value":"Type4","line":2,"start":45,"end":50},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":50,"end":51},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":53,"end":57},{"type":"T_IDENTIFIER","context":"type","value":"Baz","line":4,"start":58,"end":61},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":62,"end":63},{"type":"T_IDENTIFIER","context":"type","value":"Foo","line":4,"start":64,"end":67},{"type":"T_BIT_AND","context":"type","value":"&","line":4,"start":68,"end":69},{"type":"T_IDENTIFIER","context":"type","value":"Bar","line":4,"start":70,"end":73},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":73,"end":74}],"errors":[]}
Intersection types require all in, but one out
Intersection types are the opposite of union types. When calling a function
that accepts an intersection type, we must pass in all of those types. But
inside of our function we only have to treat it as any one of those
types.
1
2
3
4
5
6
7
8
9
10
|
// @flow
type A = Sac Vache Cuir Foncé Grainé Bleu Coccinelle Liya À Main Mnov80ynw De 1lJFKc{ a: number };
type B = { b: booleanSac Vache Cuir Foncé Grainé Bleu Coccinelle Liya À Main Mnov80ynw De 1lJFKc };
type C = { c: string };
function method(value: A & B & C) {Pâle Cuir Stacy En Seau Sac Furla Xschqze Rose 0w8Nmn
var a: A = value;
var b: BSac Vache Cuir Foncé Grainé Bleu Coccinelle Liya À Main Mnov80ynw De 1lJFKc = value;
var c: C = value;
}
|
{"value":"// @flow\ntype A = { a: number };\ntype B = { b: boolean };\ntype C = { c: string };\n\nfunction method(value: A & B & C) {\n var a: A = value;\n var b: B = value;\n var c: C = value;\n}\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"A","line":2,"start":14,"end":15},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":16,"end":17},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":18,"end":19},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":2,"start":20,"end":21},{"type":"T_COLON","context":"type","value":":","line":2,"start":21,"end":22},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":23,"end":29},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":30,"end":31},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":31,"end":32},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"B","line":3,"start":38,"end":39},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":40,"end":41},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":42,"end":43},{"type":"T_IDENTIFIER","context":"normal","value":"b","line":3,"start":44,"end":45},{"type":"T_COLON","context":"type","value":":","line":3,"start":45,"end":46},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":47,"end":54},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":55,"end":56},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":56,"end":57},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":58,"end":62},{"type":"T_IDENTIFIER","context":"type","value":"C","line":4,"start":63,"end":64},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":65,"end":66},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":67,"end":68},{"type":"T_IDENTIFIER","context":"normal","value":"c","line":4,"start":69,"end":70},{"type":"T_COLON","context":"type","value":":","line":4,"start":70,"end":71},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":72,"end":78},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":79,"end":80},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":80,"end":81},{"type":"T_FUNCTION","context":"normal","value":"function","line":6,"start":83,"end":91},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":6,"start":92,"end":98},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":98,"end":99},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":6,"start":99,"end":104},{"type":"T_COLON","context":"type","value":":","line":6,"start":104,"end":105},{"type":"T_IDENTIFIER","context":"type","value":"A","line":6,"start":106,"end":107},{"type":"T_BIT_AND","context":"type","value":"&","line":6,"start":108,"end":109},{"type":"T_IDENTIFIER","context":"type","value":"B","line":6,"start":110,"end":111},{"type":"T_BIT_AND","context":"type","value":"&","line":6,"start":112,"end":113},{"type":"T_IDENTIFIER","context":"type","value":"C","line":6,"start":114,"end":115},{"type":"T_RPAREN","context":"normal","value":")","line":6,"start":115,"end":116},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":117,"end":118},{"type":"T_VAR","context":"normal","value":"var","line":7,"start":121,"end":124},{"type":"T_IDENTIFIER","context":"normal","value":"a","line":7,"start":125,"end":126},{"type":"T_COLON","context":"type","value":":","line":7,"start":126,"end":127},{"type":"T_IDENTIFIER","context":"type","value":"A","line":7,"start":128,"end":129},{"type":"T_ASSIGN","context":"normal","value":"=","line":7,"start":130,"end":131},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":7,"start":132,"end":137},{"type":"T_SEMICOLON","context":"normal","value":";","line":7,"start":137,"end":138},{"type":"T_VAR","context":"normal","value":"var","line":8,"start":141,"end":144},{"type":"T_IDENTIFIER","context":"normal","value":"b","line":8,"start":145,"end":146},{"type":"T_COLON","context":"type","value":":","line":8,"start":146,"end":147},{"type":"T_IDENTIFIER","context":"type","value":"B","line":8,"start":148,"end":149},{"type":"T_ASSIGN","context":"normal","value":"=","line":8,"start":150,"end":151},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":8,"start":152,"end":157},{"type":"T_SEMICOLON","context":"normal","value":";","line":8,"start":157,"end":158},{"type":"T_VAR","context":"normal","value":"var","line":9,"start":161,"end":164},{"type":"T_IDENTIFIER","context":"normal","value":"c","line":9,"start":165,"end":166},{"type":"T_COLON","context":"type","value":":","line":9,"start":166,"end":167},{"type":"T_IDENTIFIER","context":"type","value":"C","line":9,"start":168,"end":169},{"type":"T_ASSIGN","context":"normal","value":"=","line":9,"start":170,"end":171},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":9,"start":172,"end":177},{"type":"T_SEMICOLON","context":"normal","value":";","line":9,"start":177,"end":178},{"type":"T_RCURLY","context":"normal","value":"}","line":10,"start":179,"end":180}],"errors":[]}
Even as we treat our value as just one of the types, we do not get an error
because it satisfies all of them.Sac Vache Cuir Foncé Grainé Bleu Coccinelle Liya À Main Mnov80ynw De 1lJFKc
Impossible intersection types
Using intersection types, it is possible to create types which are impossible
to create at runtime. Intersection types will allow you to combine any set of
types, even ones that conflict with one another.
For example, you can create an intersection of a number and a string.
{"value":"// @flow\ntype NumberAndString = number & string;\n\nfunction method(value: NumberAndString) {\n // ...\n}\n\n// $ExpectError\nmethod(3.14); // Error!\n// $ExpectError\nmethod('hi'); // Error!\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"NumberAndString","line":2,"start":14,"end":29},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":30,"end":31},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":32,"end":38},{"type":"T_BIT_AND","context":"type","value":"&","line":2,"start":39,"end":40},{"type":"T_STRING_TYPE","context":"type","value":"string","line":2,"start":41,"end":47},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":47,"end":48},{"type":"T_FUNCTION","context":"normal","value":"function","line":4,"start":50,"end":58},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":4,"start":59,"end":65},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":65,"end":66},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":4,"start":66,"end":71},{"type":"T_COLON","context":"type","value":":","line":4,"start":71,"end":72},{"type":"T_IDENTIFIER","context":"type","value":"NumberAndString","line":4,"start":73,"end":88},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":88,"end":89},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":90,"end":91},{"type":"Line","context":"comment","value":"// ...","line":5,"start":94,"end":100},{"type":"T_RCURLY","context":"normal","value":"}","line":6,"start":101,"end":102},{"type":"Line","context":"comment","value":"// $ExpectError","line":8,"start":104,"end":119},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":9,"start":120,"end":126},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":126,"end":127},{"type":"T_NUMBER","context":"normal","value":"3.14","line":9,"start":127,"end":131},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":131,"end":132},{"type":"T_SEMICOLON","context":"normal","value":";","line":9,"start":132,"end":133},{"type":"Line","context":"comment","value":"// Error!","line":9,"start":134,"end":143},{"type":"Line","context":"comment","value":"// $ExpectError","line":10,"start":144,"end":159},{"type":"T_IDENTIFIER","context":"normal","value":"method","line":11,"start":160,"end":166},{"type":"T_LPAREN","context":"normal","value":"(","line":11,"start":166,"end":167},{"type":"T_STRING","context":"normal","value":"'hi'","line":11,"start":167,"end":171},{"type":"T_RPAREN","context":"normal","value":")","line":11,"start":171,"end":172},{"type":"T_SEMICOLON","context":"normal","value":";","line":11,"start":172,"end":173},{"type":"Line","context":"comment","value":"// Error!","line":11,"start":174,"end":183}],"errors":[{"id":"E1","messages":[{"id":"E1M1","description":"Cannot call `method` with `3.14` bound to `value` because number [1] is incompatible with string [2].","context":"method(3.14); // Error!","source":"-","start":{"line":9,"column":8,"offset":127},"end":{"line":9,"column":11,"offset":131}}],"operation":null},{"id":"E2","messages":[{"id":"E2M1","description":"Cannot call `method` with `'hi'` bound to `value` because string [1] is incompatible with number [2].","context":"method('hi'); // Error!","source":"-","start":{"line":11,"column":8,"offset":167},"end":{"line":11,"column":11,"offset":171}}],"operation":null}]}
But you can’t possibly create a value which is both a number and a string,
but you can create a type for it. There’s no practical use for creating types
like this, but it’s a side effect of how intersection types work.
Intersections of object types
When you create an intersection of object types, you merge all of their
properties together.
For example, when you create an intersection of two objects with different sets
of properties, it will result in an object with all of the properties.
{"value":"// @flow\ntype One = { foo: number };\ntype Two = { bar: boolean };\n\ntype Both = One & Two;\n\nvar value: Both = {\n foo: 1,\n bar: true\n};\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"One","line":2,"start":14,"end":17},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":18,"end":19},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":2,"start":22,"end":25},{"type":"T_COLON","context":"type","value":":","line":2,"start":25,"end":26},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":27,"end":33},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":34,"end":35},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":35,"end":36},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":37,"end":41},{"type":"T_IDENTIFIER","context":"type","value":"Two","line":3,"start":42,"end":45},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":46,"end":47},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":48,"end":49},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":3,"start":50,"end":53},{"type":"T_COLON","context":"type","value":":","line":3,"start":53,"end":54},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":55,"end":62},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":63,"end":64},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":64,"end":65},{"type":"T_TYPE","context":"normal","value":"type","line":5,"start":67,"end":71},{"type":"T_IDENTIFIER","context":"type","value":"Both","line":5,"start":72,"end":76},{"type":"T_ASSIGN","context":"type","value":"=","line":5,"start":77,"end":78},{"type":"T_IDENTIFIER","context":"type","value":"One","line":5,"start":79,"end":82},{"type":"T_BIT_AND","context":"type","value":"&","line":5,"start":83,"end":84},{"type":"T_IDENTIFIER","context":"type","value":"Two","line":5,"start":85,"end":88},{"type":"T_SEMICOLON","context":"type","value":";","line":5,"start":88,"end":89},{"type":"T_VAR","context":"normal","value":"var","line":7,"start":91,"end":94},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":7,"start":95,"end":100},{"type":"T_COLON","context":"type","value":":","line":7,"start":100,"end":101},{"type":"T_IDENTIFIER","context":"type","value":"Both","line":7,"start":102,"end":106},{"type":"T_ASSIGN","context":"normal","value":"=","line":7,"start":107,"end":108},{"type":"T_LCURLY","context":"normal","value":"{","line":7,"start":109,"end":110},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":8,"start":113,"end":116},{"type":"T_COLON","context":"normal","value":":","line":8,"start":116,"end":117},{"type":"T_NUMBER","context":"normal","value":"1","line":8,"start":118,"end":119},{"type":"T_COMMA","context":"normal","value":",","line":8,"start":119,"end":120},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":9,"start":123,"end":126},{"type":"T_COLON","context":"normal","value":":","line":9,"start":126,"end":127},{"type":"T_TRUE","context":"normal","value":"true","line":9,"start":128,"end":132},{"type":"T_RCURLY","context":"normal","value":"}","line":10,"start":133,"end":134},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":134,"end":135}],"errors":[]}
But when you have properties that overlap by having the same name, it creates
an intersection of the property type as well.
For example, if you merge two objects with a property named prop, one with a
type of number and another with a type of boolean, the resulting object will
have an intersection of number and boolean.
Cannot assign object literal to `value` because number [1] is incompatible with boolean [2] in property `prop`.
{"value":"// @flow\ntype One = { prop: number };\ntype Two = { prop: boolean };\n\ntype Both = One & Two;\n\n// $ExpectError\nvar value: Both = {\n prop: 1 // Error!\n};\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"One","line":2,"start":14,"end":17},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":18,"end":19},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":20,"end":21},{"type":"T_IDENTIFIER","context":"normal","value":"prop","line":2,"start":22,"end":26},{"type":"T_COLON","context":"type","value":":","line":2,"start":26,"end":27},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":28,"end":34},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":35,"end":36},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":36,"end":37},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":38,"end":42},{"type":"T_IDENTIFIER","context":"type","value":"Two","line":3,"start":43,"end":46},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":47,"end":48},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":49,"end":50},{"type":"T_IDENTIFIER","context":"normal","value":"prop","line":3,"start":51,"end":55},{"type":"T_COLON","context":"type","value":":","line":3,"start":55,"end":56},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":57,"end":64},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":65,"end":66},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":66,"end":67},{"type":"T_TYPE","context":"normal","value":"type","line":5,"start":69,"end":73},{"type":"T_IDENTIFIER","context":"type","value":"Both","line":5,"start":74,"end":78},{"type":"T_ASSIGN","context":"type","value":"=","line":5,"start":79,"end":80},{"type":"T_IDENTIFIER","context":"type","value":"One","line":5,"start":81,"end":84},{"type":"T_BIT_AND","context":"type","value":"&","line":5,"start":85,"end":86},{"type":"T_IDENTIFIER","context":"type","value":"Two","line":5,"start":87,"end":90},{"type":"T_SEMICOLON","context":"type","value":";","line":5,"start":90,"end":91},{"type":"Line","context":"comment","value":"// $ExpectError","line":7,"start":93,"end":108},{"type":"T_VAR","context":"normal","value":"var","line":8,"start":109,"end":112},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":8,"start":113,"end":118},{"type":"T_COLON","context":"type","value":":","line":8,"start":118,"end":119},{"type":"T_IDENTIFIER","context":"type","value":"Both","line":8,"start":120,"end":124},{"type":"T_ASSIGN","context":"normal","value":"=","line":8,"start":125,"end":126},{"type":"T_LCURLY","context":"normal","value":"{","line":8,"start":127,"end":128},{"type":"T_IDENTIFIER","context":"normal","value":"prop","line":9,"start":131,"end":135},{"type":"T_COLON","context":"normal","value":":","line":9,"start":135,"end":136},{"type":"T_NUMBER","context":"normal","value":"1","line":9,"start":137,"end":138},{"type":"Line","context":"comment","value":"// Error!","line":9,"start":139,"end":148},{"type":"T_RCURLY","context":"normal","value":"}","line":10,"start":149,"end":150},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":150,"end":151}],"errors":[{"id":"E1","messages":[{"id":"E1M1","description":"Cannot assign object literal to `value` because number [1] is incompatible with boolean [2] in property `prop`.","context":"var value: Both = {","source":"-","start":{"line":8,"column":19,"offset":127},"end":{"line":10,"column":1,"offset":150}}],"operation":null}]}