/
githubmirror
/
immutable-js
Обзор
Документация
Войти
/
githubmirror
/
immutable-js
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
type-definitions/flow-tests/immutable-flow.js
1 341 строка
46 KB
Adam Buechler
Add failing type tests for first() and last()
21 июн 2024, 09:05
21 июн 2024, 09:05
07d057c
Код
Авторство
О чём код?
// @flow // Some tests look like they are repeated in order to avoid false positives. // Flow might not complain about an instance of (what it thinks is) T to be assigned to T<K, V> import Immutable, { List, Map, Stack, Set, Seq, Range, Repeat, Record, OrderedMap, OrderedSet, get, getIn, has, hasIn, merge, mergeDeep, mergeWith, mergeDeepWith, remove, removeIn, set, setIn, update, updateIn, } from 'immutable'; import * as Immutable2 from 'immutable'; import type { KeyedCollection, IndexedCollection, SetCollection, KeyedSeq, IndexedSeq, SetSeq, RecordFactory, RecordOf, } from 'immutable'; /** * Although this looks like dead code, importing `Immutable` and * `Immutable2` tests: * * 1. that default import works -- `import Immutable, {...} from 'immutable' * 2. that importing everything works -- `import * as X from 'immutable'` * 3. that individual imports are supported */ const ImmutableList = Immutable.List; const ImmutableMap = Immutable.Map; const ImmutableStack = Immutable.Stack; const ImmutableSet = Immutable.Set; const ImmutableKeyedCollection: KeyedCollection< *, * > = Immutable.Collection.Keyed(); const ImmutableRange = Immutable.Range; const ImmutableRepeat = Immutable.Repeat; const ImmutableIndexedSeq: IndexedSeq<*> = Immutable.Seq.Indexed(); const Immutable2List = Immutable2.List; const Immutable2Map = Immutable2.Map; const Immutable2Stack = Immutable2.Stack; const Immutable2Set = Immutable2.Set; const Immutable2KeyedCollection: Immutable2.KeyedCollection< *, * > = Immutable2.Collection.Keyed(); const Immutable2Range = Immutable2.Range; const Immutable2Repeat = Immutable2.Repeat; const Immutable2IndexedSeq: Immutable2.IndexedSeq<*> = Immutable2.Seq.Indexed(); var defaultExport: List<*> = Immutable.List(); var moduleExport: List<*> = Immutable2.List(); var numberList: List<number> = List(); var numberOrStringList: List<string | number> = List(); var nullableNumberList: List<?number> = List(); var stringToNumber: Map<string, number> = Map(); var orderedStringToNumber: OrderedMap<string, number> = OrderedMap(); var orderedStringToString: OrderedMap<string, string> = OrderedMap(); var orderedStringToNumberOrString: OrderedMap< string, string | number > = OrderedMap(); var orderedNumberToString: OrderedMap<number, string> = OrderedMap(); var orderedNumberToNumber: OrderedMap<number, number> = OrderedMap(); var stringToNumberOrString: Map<string, string | number> = Map(); var numberToString: Map<number, string> = Map(); var stringOrNumberToNumberOrString: Map< string | number, string | number > = Map(); var anyMap: Map<any, any> = Map(); var numberSet: Set<number> = Set(); var orderedStringSet: OrderedSet<string> = OrderedSet(); var orderedNumberSet: OrderedSet<number> = OrderedSet(); var orderedNumberOrStringSet: OrderedSet<string | number> = OrderedSet(); var numberOrStringSet: Set<number | string> = Set(); var stringSet: Set<string> = Set(); var numberStack: Stack<number> = Stack(); var numberOrStringStack: Stack<string | number> = Stack(); var number: number = 0; var stringToNumberCollection: KeyedCollection<string, number> = stringToNumber; var numberToStringCollection: KeyedCollection<number, string> = numberToString; var partitions: [List<number>, List<number>]; numberList = List([1, 2]); var numberListSize: number = numberList.size; numberOrStringList = List(['a', 1]); // $FlowExpectedError[incompatible-call] numberList = List(['a', 'b']); numberList = List.of(1, 2); numberOrStringList = List.of('a', 1); // $FlowExpectedError[incompatible-call] numberList = List.of('a', 1); numberList = List().set(0, 0); numberOrStringList = List.of(0).set(1, 'a'); // $FlowExpectedError[incompatible-call] numberList = List().set(0, 'a'); numberList = List.of(1, 2, 3); // $FlowExpectedError[incompatible-type] var item: number = numberList.get(4); var nullableItem: ?number = numberList.get(4); var itemOrDefault: number = numberList.get(4, 10); // $FlowExpectedError[incompatible-type] var item: number = numberList.first(); // $FlowExpectedError[incompatible-type] var func: () => number = () => numberList.first(); // $FlowExpectedError[incompatible-type] var item: number = numberList.last(); // $FlowExpectedError[incompatible-type] var func: () => number = () => numberList.last(); numberList = List().insert(0, 0); numberOrStringList = List.of(0).insert(1, 'a'); // $FlowExpectedError[incompatible-call] numberList = List().insert(0, 'a'); numberList = List().push(1, 1); numberOrStringList = List().push(1, 'a'); // $FlowExpectedError[incompatible-call] numberList = List().push(0, 'a'); numberList = List().unshift(1, 1); numberOrStringList = List().unshift(1, 'a'); // $FlowExpectedError[incompatible-call] numberList = List().unshift(0, 'a'); numberList = List.of(1).delete(0); // $FlowExpectedError[incompatible-call] numberList = List.of('a').delete(0); numberList = List.of(1).remove(0); // $FlowExpectedError[incompatible-call] numberList = List.of('a').remove(0); numberList = List.of(1).clear(); // $FlowExpectedError[incompatible-call] numberList = List.of('a').clear(); numberList = List.of(1).pop(); // $FlowExpectedError[incompatible-call] numberList = List.of('a').pop(); numberList = List.of(1).shift(); // $FlowExpectedError[incompatible-call] numberList = List.of('a').shift(); numberList = List.of('a').update((value) => List.of(1)); // $FlowExpectedError[incompatible-call] numberList = List.of(1).update((value) => List.of('a')); numberOrStringList = List.of('a').update(0, (value) => 1); // $FlowExpectedError[incompatible-call] numberList = List.of(1).update(0, (value) => 'a'); numberOrStringList = List.of(1).update(1, 0, (value) => 'a'); // $FlowExpectedError[incompatible-call] numberList = List.of(1).update(1, 0, (value) => 'a'); numberList = List.of(1).merge(List.of(2)); numberOrStringList = List.of('a').merge(List.of(1)); // $FlowExpectedError[incompatible-call] numberList = List.of('a').merge(List.of(1)); // Functional API numberList = merge(List([1]), List([2])); numberOrStringList = merge<List<string | number>>(List(['a']), List([1])); // $FlowExpectedError[incompatible-call] numberList = merge(List(['a']), List([1])); nullableNumberList = List.of(1).setSize(2); // $FlowExpectedError[incompatible-type] setIn [] replaces the top-most value. number ~> List<number> numberList = List([1]).setIn([], 0); { const x: number = List([1]).setIn([], 0); } // $FlowExpectedError[incompatible-call] "a" is not a valid key for List. numberList = List([1]).setIn(['a'], 0); // $FlowExpectedError[incompatible-type-arg] "a" is not a valid value for List of number. numberList = List([1]).setIn([0], 'a'); numberList = List([1]).setIn([0], 0); // $FlowExpectedError[incompatible-call] "a" is not a valid key for List. List([List([List([1])])]).setIn([0, 0, 'a'], 'a'); // $FlowExpectedError[incompatible-call] "a" is not a valid value for List of number. List([List([List([1])])]).setIn([0, 0, 0], 'a'); List([List([List([1])])]).setIn([0, 0, 0], 123); // $FlowExpectedError[incompatible-type] deleteIn [] replaces the top-most value. void ~> List<number> numberList = List([1]).deleteIn([]); { const x: void = List([1]).deleteIn([]); } // $FlowExpectedError[incompatible-type] numberList = List([1]).removeIn([]); // $FlowExpectedError[incompatible-call] "a" is not a valid key for List. numberList = List([1]).deleteIn(['a']); // $FlowExpectedError[incompatible-call] numberList = List([1]).removeIn(['a']); numberList = List([1]).deleteIn([0]); numberList = List([1]).removeIn([0]); // Functional API // $FlowExpectedError[incompatible-type] deleteIn [] replaces the top-most value. void ~> List<number> numberList = removeIn(List([1]), []); { const x: void = removeIn(List([1]), []); } // $FlowExpectedError[incompatible-call] "a" is not a valid key for List. numberList = removeIn(List([1]), ['a']); numberList = removeIn(List([1]), [0]); // $FlowExpectedError[incompatible-type] updateIn [] replaces the top-most value. number ~> List<number> numberList = List([1]).updateIn([], () => 123); { const x: number = List([1]).updateIn([], () => 123); } // $FlowExpectedError[incompatible-call] - 'a' is not a number numberList = List([1]).updateIn([0], (val) => 'a'); // $FlowExpectedError[incompatible-call] numberList = List([1]).updateIn([0], 0, (val) => 'a'); // $FlowExpectedError[incompatible-call] - 'a' in an invalid argument numberList = List([1]).updateIn([0], 'a'); // $FlowExpectedError[incompatible-call] numberList = List([1]).updateIn([0], 0, 'a'); numberList = List([1]).updateIn([0], (val) => val + 1); numberList = List([1]).updateIn([0], 0, (val) => val + 1); numberList = List.of(1).mergeIn([], []); numberList = List.of(1).mergeDeepIn([], []); numberList = List.of(1).withMutations((mutable) => mutable); numberList = List.of(1).asMutable(); numberList = List.of(1).asImmutable(); numberList = List.of(1).map((value, index, iter) => 1); // $FlowExpectedError[incompatible-call] numberList = List.of(1).map((value, index, iter) => 'a'); numberList = List.of(1).flatMap((value, index, iter) => [1]); // $FlowExpectedError[incompatible-call] numberList = List.of(1).flatMap((value, index, iter) => ['a']); numberList = List.of(1).flatten(); // Specific type for filter(Boolean) which removes nullability. numberList = nullableNumberList.filter(Boolean); partitions = List([1,2,3]).partition(value => value % 2); /* Map */ stringToNumber = Map(); let stringToNumberSize: number = stringToNumber.size; stringToNumberOrString = Map(); numberToString = Map(); stringToNumber = Map({ a: 1 }); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 'a' }); stringToNumber = Map([['a', 1]]); stringToNumber = Map(List([['a', 1]])); // $FlowExpectedError[incompatible-call] stringToNumber = Map([['a', 'b']]); // $FlowExpectedError[incompatible-call] -- this is actually a Map<string, string> stringToNumber = Map(List([['a', 'a']])); // $FlowFixMe[incompatible-call] - This is Iterable<Iterable<string>>, ideally it could be interpreted as Iterable<[string, string]> stringToNumber = Map(List([List(['a', 'a'])])); stringOrNumberToNumberOrString = Map({ a: 'a' }).set('b', 1).set(2, 'c'); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 0 }).set('b', ''); // $FlowExpectedError[incompatible-call] stringToNumber = Map().set(1, ''); // Functional API stringToNumber = set(set(Map({ a: 0 }), 'b', 1), 'c', 2); // $FlowExpectedError[incompatible-call] - Functional API currently requires arguments to have the same value types. stringOrNumberToNumberOrString = set(set(Map({ a: 'a' }), 'b', 1), 2, 'c'); // $FlowExpectedError[incompatible-call] stringToNumber = set(Map({ a: 0 }), 'b', ''); // $FlowExpectedError[incompatible-call] stringToNumber = set(Map(), 1, ''); stringToNumber = Map({ a: 0 }).delete('a'); stringToNumber = Map({ a: 0 }).remove('a'); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 0 }).delete(1); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 0 }).remove(1); stringToNumber = Map({ a: 0 }).deleteAll(['a']); stringToNumber = Map({ a: 0 }).removeAll(['a']); // $FlowExpectedError[prop-missing] stringToNumber = Map({ a: 0 }).deleteAll(1); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 0 }).deleteAll([1]); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 0 }).removeAll([1]); stringToNumber = Map({ a: 0 }).clear(); stringToNumber = Map({ a: 1 }).update((value) => Map({ a: 1 })); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).update((value) => Map({ '1': 'a' })); stringToNumberOrString = Map({ a: 1 }).update('a', (value) => 'a'); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).update('a', (value) => 'a'); stringToNumberOrString = Map({ a: 1 }).update('a', 'b', (value) => 'a'); // $FlowExpectedError[incompatible-type-arg] // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).update('a', 'b', (value) => 'a'); // $FlowExpectedError[incompatible-type-arg] stringToNumberOrString = Map({ a: 1 }).merge({ a: { a: '1' } }); // $FlowExpectedError[incompatible-type-arg] stringToNumberOrString = Map({ a: 1 }).update('a', 'b', (value) => { a: '1'; }); stringToNumber = Map({ a: 1 }).merge(Map({ a: 1 })); stringToNumberOrString = Map({ a: 1 }).merge({ a: 'b' }); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).merge({ a: 'b' }); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).merge([[1, 'a']]); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).merge(numberToString); // Functional API stringToNumber = merge(Map({ a: 1 }), Map({ a: 1 })); // $FlowExpectedError[incompatible-call] - Functional API currently requires arguments to have the same value types. stringToNumberOrString = merge(Map({ a: 1 }), { a: 'b' }); // $FlowExpectedError[incompatible-call] stringToNumber = merge(Map({ a: 1 }), { a: 'b' }); // $FlowExpectedError[incompatible-call] stringToNumber = merge(Map({ a: 1 }), [[1, 'a']]); // $FlowExpectedError[incompatible-call] stringToNumber = merge(Map({ a: 1 }), numberToString); stringToNumber = Map({ a: 1 }).mergeWith((previous, next, key) => 1, { a: 2, b: 2, }); stringToNumber = Map({ a: 1 }).mergeWith( // $FlowExpectedError[incompatible-call] (previous, next, key) => previous + next, // $FlowExpectedError[incompatible-type-arg] { a: '2', b: '2' } ); stringToNumberOrString = Map({ a: 1 }).mergeWith( (previous, next, key) => previous + next, { a: '2', b: '2' } ); // $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument stringToNumber = Map({ a: 1 }).mergeWith((previous, next, key) => 1, [1]); stringToNumberOrString = Map({ a: 1 }).mergeDeep({ a: 'b' }); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).mergeDeep({ a: 'b' }); stringToNumber = Map({ a: 1 }).mergeDeepWith((previous, next, key) => 1, { a: 2, b: 2, }); stringToNumber = Map({ a: 1 }).mergeDeepWith( (previous, next, key) => 1, // $FlowExpectedError[incompatible-type-arg] { a: '2', b: '2' } ); stringToNumberOrString = Map({ a: 1 }).mergeDeepWith( (previous, next, key) => 1, { a: '2', b: '2' } ); // $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument stringToNumber = Map({ a: 1 }).mergeDeepWith((previous, next, key) => 1, [1]); // KeyedSeq can merge into Map var stringToStringSeq: KeyedSeq<string, string> = Seq({ b: 'B' }); stringToNumberOrString = Map({ a: 1 }).merge(stringToStringSeq); // $FlowExpectedError[incompatible-type] stringToNumber = Map({ a: 1 }).setIn([], 0); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).setIn(['a'], 'a'); stringToNumber = Map({ a: 1 }).setIn(['a'], 0); // $FlowExpectedError[incompatible-type] stringToNumber = Map({ a: 1 }).deleteIn([]); // $FlowExpectedError[incompatible-type] stringToNumber = Map({ a: 1 }).removeIn([]); stringToNumber = Map({ a: 1 }).deleteIn(['a']); stringToNumber = Map({ a: 1 }).removeIn(['a']); // $FlowExpectedError[incompatible-type] Map({ a: 1 }).updateIn([], (v) => v + 1); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).updateIn(['a'], (v) => 'a'); stringToNumber = Map({ a: 1 }).updateIn(['a'], (v) => v + 1); stringToNumber = Map({ a: 1 }).updateIn(['a'], 0, (v) => v + 1); Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 'z'], (v) => v + 1); Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn( ['x', 'y', 'z'], 0, (v) => v + 1 ); // $FlowExpectedError[incompatible-call] Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 1], (v) => v + 1); // $FlowExpectedError[incompatible-call] Map({ x: Map({ y: Map({ z: 1 }) }) }).updateIn(['x', 'y', 'z'], (v) => 'a'); stringToNumber = Map({ a: 1 }).mergeIn([], []); stringToNumber = Map({ a: 1 }).mergeDeepIn([], []); anyMap = Map({ a: {} }).mergeIn(['a'], Map({ b: 2 })); anyMap = Map({ a: {} }).mergeDeepIn(['a'], Map({ b: 2 })); anyMap = Map({ a: {} }).mergeIn(['a'], List([1, 2])); anyMap = Map({ a: {} }).mergeDeepIn(['a'], List([1, 2])); anyMap = Map({ a: {} }).mergeIn(['a'], { b: 2 }); anyMap = Map({ a: {} }).mergeDeepIn(['a'], { b: 2 }); // $FlowExpectedError[incompatible-call]: not iterable / object anyMap = Map({ a: {} }).mergeIn(['a'], 1); // $FlowExpectedError[incompatible-call]: not iterable / object anyMap = Map({ a: {} }).mergeDeepIn(['a'], 1); // $FlowExpectedError[incompatible-type-arg]: bad key type stringToNumber = Map({ a: {} }).mergeIn([1], { b: 2 }); // $FlowExpectedError[incompatible-type-arg]: bad key type stringToNumber = Map({ a: {} }).mergeDeepIn([1], { b: 2 }); stringToNumber = Map({ a: 1 }).withMutations((mutable) => mutable); stringToNumber = Map({ a: 1 }).asMutable(); stringToNumber = Map({ a: 1 }).asImmutable(); stringToNumber = Map({ a: 1 }).map((value, index, iter) => 1); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).map((value, index, iter) => 'a'); stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => [['b', 1]]); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => [['a', 'a']]); // $FlowExpectedError[incompatible-call] stringToNumber = Map({ a: 1 }).flatMap((value, index, iter) => Map({ a: 'a' })); numberToString = Map({ a: 1 }).flip(); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).flip(); numberToString = Map({ a: 'a' }).mapKeys((key, value, iter) => 1); // $FlowExpectedError[incompatible-type-arg] stringToNumber = Map({ a: 1 }).mapKeys((key, value, iter) => 1); anyMap = Map({ a: 1 }).flatten(); var stringToNullableNumber = Map({ a: 1, b: null }); // $FlowExpectedError[incompatible-type-arg] stringToNumber = stringToNullableNumber; // Specific type for filter(Boolean) which removes nullability. stringToNumber = stringToNullableNumber.filter(Boolean); [anyMap, ] = Map({ "a": 1, "b": 2}).partition((key, index, iter) => key % 2) /* OrderedMap */ orderedStringToNumber = Map({ a: 1 }).toOrderedMap(); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string,string> orderedStringToNumber = Map({ a: 'b' }).toOrderedMap(); orderedStringToString = Map({ a: 'b' }).toOrderedMap(); orderedStringToNumber = OrderedMap({ a: 1 }); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, string> orderedStringToNumber = OrderedMap({ a: '1' }); orderedStringToString = OrderedMap({ a: '1' }); orderedStringToNumber = OrderedMap(Map({ a: 1 })); // $FlowExpectedError[incompatible-type-arg] - it's actually an OrderedMap<string, string> orderedStringToNumber = OrderedMap(Map({ a: '1' })); orderedStringToNumber = OrderedMap(); orderedStringToNumber = OrderedMap().set('b', 2); // $FlowExpectedError[incompatible-call] - this is actually an OrderedMap<string, string> orderedStringToNumber = OrderedMap().set('b', '2'); orderedStringToString = OrderedMap().set('b', '2'); orderedStringToNumber = OrderedMap({ a: 1 }).delete('a'); orderedStringToNumber = OrderedMap({ a: 1 }).remove('a'); orderedStringToNumber = OrderedMap({ a: 1 }).clear(); orderedStringToNumber = OrderedMap({ a: 1 }).update(() => OrderedMap({ b: 1 })); /** * TODO: the following is valid but I question if it should be valid: * * ``` * const x: OrderedMap<string, string> = OrderedMap({'a': 1}) * .update(() => OrderedMap({'b': '1'})) * ``` * * In the above example, `update` is changing an OrderedMap<string, number> to an OrderedMap<string, string> * This seems inconsistent with the typescript signature of * * ``` * update(updater: (value: Map<K, V>) => Map<K, V>): Map<K, V> * ``` */ orderedStringToNumber = OrderedMap({ a: 1 }).update(() => // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, string> OrderedMap({ b: '1' }) ); orderedStringToString = OrderedMap({ a: 1 }).update(() => OrderedMap({ b: '1' }) ); orderedStringToNumber = OrderedMap({ a: 1 }).update('a', (value) => value + 1); /** * TODO: is the below the intended functionality? The typescript signature looks like * * ``` * update(key: K, updater: (value: V) => V): Map<K, V>; * ``` * * so it seems like in this case the updater should only be able to return numbers. * This comment applies to all of the update / merge functions in Map and OrderedMap */ // $FlowExpectedError[incompatible-call] - this is actually an OrderedMap<string, number|string> orderedStringToNumber = OrderedMap({ a: 1 }).update('a', () => 'b'); orderedStringToNumberOrString = OrderedMap({ a: 1 }).update('a', () => 'b'); orderedStringToNumber = OrderedMap({ a: 1 }).update( 'a', 0, (value) => value + 1 ); // $FlowExpectedError[incompatible-call] - this is actually an OrderedMap<string, number|string> orderedStringToNumber = OrderedMap({ a: 1 }).update('a', 0, () => 'b'); orderedStringToNumberOrString = OrderedMap({ a: 1 }).update('a', 0, () => 'b'); orderedStringToNumber = OrderedMap({ a: 1 }).merge({ b: 2 }); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, number|string> orderedStringToNumber = OrderedMap({ a: 1 }).merge({ b: '2' }); orderedStringToNumberOrString = OrderedMap({ a: 1 }).merge({ b: '2' }); orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith( (prev, next) => next, { a: 2, b: 3 } ); orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith( // $FlowExpectedError[incompatible-call] (prev, next) => next, // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, number|string> { a: '2', b: '3' } ); orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeWith( (prev, next) => next, { a: '2', b: '3' } ); // $FlowExpectedError[incompatible-call] - the array [1] is not a valid argument orderedStringToNumber = OrderedMap({ a: 1 }).mergeWith((prev, next) => next, [ 1, ]); orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeep({ a: 2 }); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, number|string> orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeep({ a: '2' }); orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeDeep({ a: '2' }); orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( (prev, next) => next, { a: 2, b: 3 } ); orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( (prev, next) => next, // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<string, number|string> { a: '2', b: '3' } ); orderedStringToNumberOrString = OrderedMap({ a: 1 }).mergeDeepWith( (prev, next) => next, { a: '2', b: '3' } ); orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepWith( (prev, next) => next, // $FlowExpectedError[incompatible-call] - the array [1] is an invalid argument [1] ); // $FlowExpectedError[incompatible-type] orderedStringToNumber = OrderedMap({ a: 1 }).setIn([], 3); // $FlowExpectedError[incompatible-type-arg] orderedStringToNumber = OrderedMap({ a: 1 }).setIn([1], 3); orderedStringToNumber = OrderedMap({ a: 1 }).setIn(['a'], 3); // $FlowExpectedError[incompatible-type] orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn([]); // $FlowExpectedError[incompatible-type] orderedStringToNumber = OrderedMap({ a: 1 }).removeIn([]); // $FlowExpectedError[incompatible-type-arg] orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn([1]); // $FlowExpectedError[incompatible-type-arg] orderedStringToNumber = OrderedMap({ a: 1 }).removeIn([1]); orderedStringToNumber = OrderedMap({ a: 1 }).deleteIn(['b']); orderedStringToNumber = OrderedMap({ a: 1 }).removeIn(['b']); // $FlowExpectedError[incompatible-type] orderedStringToNumber = OrderedMap({ a: 1 }).updateIn([], (v) => v + 1); // $FlowExpectedError[incompatible-type-arg] orderedStringToNumber = OrderedMap({ a: 1 }).updateIn([1], (v) => v + 1); // $FlowExpectedError[incompatible-call] orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], (v) => 'a'); orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], (v) => v + 1); orderedStringToNumber = OrderedMap({ a: 1 }).updateIn(['a'], 0, (v) => v + 1); // $FlowExpectedError[incompatible-call] OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 1], (v) => v + 1); // $FlowExpectedError[incompatible-call] OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], (v) => 'a'); OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], (v) => v + 1); OrderedMap({ x: OrderedMap({ y: 1 }) }).updateIn(['x', 'y'], 0, (v) => v + 1); orderedStringToNumber = OrderedMap({ a: 1 }).mergeIn([], { b: 2 }); orderedStringToNumber = OrderedMap({ a: 1 }).mergeDeepIn([], { b: 2 }); orderedStringToNumber = OrderedMap({ a: 1 }).withMutations((mutable) => mutable.set('b', 2) ); orderedStringToNumber = OrderedMap({ a: 1 }).asMutable(); orderedStringToNumber = OrderedMap({ a: 1 }).asImmutable(); orderedStringToNumber = OrderedMap({ a: 1 }).map((v) => v + 1); // $FlowExpectedError[incompatible-call] - this is actually an OrderedMap<string, string> orderedStringToNumber = OrderedMap({ a: 1 }).map(() => 'a'); orderedStringToString = OrderedMap({ a: 1 }).map(() => 'a'); orderedStringToNumber = OrderedMap({ a: 1 }).flatMap((v, k) => OrderedMap({ [k]: v + 1 }) ); orderedStringToNumber = OrderedMap({ a: 1 }).flatMap((v, k) => // $FlowExpectedError[incompatible-call] - string "a" is not a number OrderedMap({ [k]: 'a' }) ); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<number, string> orderedStringToNumber = OrderedMap({ a: 1 }).flip(); orderedNumberToString = OrderedMap({ a: 1 }).flip(); orderedStringToNumber = OrderedMap({ a: 1 }).mapKeys((x) => x); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedMap<number, number> orderedStringToNumber = OrderedMap({ a: 1 }).mapKeys((x) => 1); orderedNumberToNumber = OrderedMap({ a: 1 }).mapKeys((x) => 1); orderedStringToNumber = OrderedMap({ a: 1 }).flatten(); orderedStringToNumber = OrderedMap({ a: 1 }).flatten(1); orderedStringToNumber = OrderedMap({ a: 1 }).flatten(true); // $FlowExpectedError[incompatible-call] - 'a' is an invalid argument orderedStringToNumber = OrderedMap({ a: 1 }).flatten('a'); /* Set */ numberSet = Set(); numberOrStringSet = Set(); stringSet = Set(); numberSet = Set([1, 2, 3]); // $FlowExpectedError[incompatible-call] numberSet = Set(['a', 'b']); numberSet = Set.of(1, 2); // $FlowExpectedError[incompatible-call] numberSet = Set.of('a', 'b'); numberSet = Set.fromKeys(Map().set(1, '')); stringSet = Set.fromKeys({ a: '' }); // $FlowExpectedError[incompatible-type-arg] numberSet = Set.fromKeys(Map({ a: 1 })); // $FlowExpectedError[incompatible-type-arg] numberSet = Set.fromKeys({ a: 1 }); numberOrStringSet = Set([1]).add('a'); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).add('s'); numberSet = Set([1]).delete(1); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).delete('a'); // $FlowExpectedError[incompatible-call] numberSet = Set(['a']).delete('a'); numberSet = Set([1]).remove(1); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).remove('a'); // $FlowExpectedError[incompatible-call] numberSet = Set(['a']).remove('a'); numberSet = Set([1]).clear(); // $FlowExpectedError[incompatible-call] numberSet = Set(['a']).clear(); numberOrStringSet = Set(['a']).union([1]); numberOrStringSet = Set(['a']).union(Set([1])); numberSet = Set([1]).union([1]); numberSet = Set([1]).union(Set([1])); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).union(['a']); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).union(Set(['a'])); numberOrStringSet = Set(['a']).merge([1]); numberOrStringSet = Set(['a']).merge(Set([1])); numberSet = Set([1]).merge([1]); numberSet = Set([1]).merge(Set([1])); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).merge(['a']); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).merge(Set(['a'])); numberSet = Set([1]).intersect(Set([1])); numberSet = Set([1]).intersect([1]); numberSet = Set([1]).intersect(Set(['a'])); numberSet = Set([1]).intersect(['a']); numberSet = Set([1]).subtract(Set([1])); numberSet = Set([1]).subtract([1]); numberSet = Set([1]).subtract(Set(['a'])); numberSet = Set([1]).subtract(['a']); numberSet = Set([1]).withMutations((mutable) => mutable); // $FlowExpectedError[incompatible-call] stringSet = Set([1]).withMutations((mutable) => mutable); numberSet = Set([1]).asMutable(); // $FlowExpectedError[incompatible-call] stringSet = Set([1]).asMutable(); numberSet = Set([1]).asImmutable(); // $FlowExpectedError[incompatible-call] stringSet = Set([1]).asImmutable(); stringSet = Set([1]).map((value, index, iter) => 'a'); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).map((value, index, iter) => 'a'); stringSet = Set([1]).flatMap((value, index, iter) => ['a']); // $FlowExpectedError[incompatible-call] numberSet = Set([1]).flatMap((value, index, iter) => ['a']); numberSet = Set([1]).flatten(); /* OrderedSet */ orderedStringSet = Set(['a']).toOrderedSet(); // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number> orderedStringSet = Set([1]).toOrderedSet(); orderedNumberSet = Set([1]).toOrderedSet(); orderedStringSet = OrderedSet(['a']); // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number> orderedStringSet = OrderedSet([1]); orderedNumberSet = OrderedSet([1]); orderedStringSet = OrderedSet(List.of('a')); // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number> orderedStringSet = OrderedSet(List.of(1)); orderedNumberSet = OrderedSet(List.of(1)); orderedStringSet = OrderedSet.of('a', 'b', 'c'); // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number> orderedStringSet = OrderedSet.of(1); orderedNumberSet = OrderedSet.of(1); orderedStringSet = OrderedSet.fromKeys(Map({ a: 1 })); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedSet<string> orderedNumberSet = OrderedSet.fromKeys(Map({ a: 1 })); orderedStringSet = OrderedSet.fromKeys({ a: 1 }); // $FlowExpectedError[incompatible-type-arg] - this is actually an OrderedSet<string> orderedNumberSet = OrderedSet.fromKeys({ a: 1 }); orderedStringSet = OrderedSet(); orderedStringSet = OrderedSet.of('a').add('b'); /** * TODO: in typescript definitions, add looks like * * ``` * add(value: T): Set<T> * ``` * * so we shouldn't be able to add a number to a set of strings */ // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number|string> orderedStringSet = OrderedSet('a').add(1); orderedNumberOrStringSet = OrderedSet('a').add(1); orderedStringSet = OrderedSet.of('a').delete('a'); // $FlowExpectedError[incompatible-call] - 1 is an invalid arg orderedStringSet = OrderedSet.of('a').delete(1); orderedStringSet = OrderedSet.of('a').remove('a'); // $FlowExpectedError[incompatible-call] - 1 is an invalid arg orderedStringSet = OrderedSet.of('a').remove(1); orderedStringSet = OrderedSet.of('a').clear(); orderedStringSet = OrderedSet.of('a').union(OrderedSet.of('b')); /** * TODO: typescript def looks like * * ``` * union(...iterables: Array<T>[]): Set<T> * ``` * * so we shouldn't be able to merge strings and numbers */ // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number|string> orderedStringSet = OrderedSet.of('a').union(OrderedSet.of(1)); orderedNumberOrStringSet = OrderedSet.of('a').union(OrderedSet.of(1)); orderedStringSet = OrderedSet.of('a').merge(OrderedSet.of('b')); /** * TODO: typescript def looks like * * ``` * merge(...iterables: Array<T>[]): Set<T> * ``` * * so we shouldn't be able to merge strings and numbers */ // $FlowExpectedError[incompatible-call] - this is actually an OrderedSet<number|string> orderedStringSet = OrderedSet.of('a').merge(OrderedSet.of(1)); orderedNumberOrStringSet = OrderedSet.of('a').merge(OrderedSet.of(1)); orderedStringSet = OrderedSet.of('a', 'b').intersect(OrderedSet.of('a')); /** * TODO: typescript def looks like * * ``` * intersect(...iterables: Array<T>[]): Set<T> * ``` * * so we shouldn't be able to intersect strings and numbers */ orderedStringSet = OrderedSet.of('a', 'b').intersect(OrderedSet.of(1)); orderedStringSet = OrderedSet.of('a', 'b').subtract(OrderedSet.of('a')); /** * TODO: typescript def looks like * * ``` * subtract(...iterables: Array<T>[]): Set<T> * ``` * * so we shouldn't be able to intersect strings and numbers */ orderedStringSet = OrderedSet.of('a', 'b').subtract(OrderedSet.of(1)); orderedStringSet = OrderedSet().withMutations((mutable) => mutable.add('a')); orderedStringSet = OrderedSet.of('a').asMutable(); orderedStringSet = OrderedSet.of('a').asImmutable(); orderedStringSet = OrderedSet.of('a', 'b').map((m) => m); // $FlowExpectedError[incompatible-call] - this is an OrderedSet<number> orderedStringSet = OrderedSet.of('a', 'b').map(() => 1); orderedNumberSet = OrderedSet.of('a', 'b').map(() => 1); orderedStringSet = OrderedSet.of('a', 'b').flatMap((m) => [m]); // $FlowExpectedError[incompatible-call] - this is an OrderedSet<number> orderedStringSet = OrderedSet.of('a', 'b').flatMap((m) => [1]); orderedNumberSet = OrderedSet.of('a', 'b').flatMap((m) => [1]); orderedStringSet = OrderedSet.of('a', 'b').flatten(1); orderedStringSet = OrderedSet.of('a', 'b').flatten(false); // $FlowExpectedError[incompatible-call] - invalid arg for flatten orderedStringSet = OrderedSet.of('a', 'b').flatten('a'); /* Stack */ numberStack = Stack([1, 2]); let numberStackSize: number = numberStack.size; numberOrStringStack = Stack(['a', 1]); // $FlowExpectedError[incompatible-call] numberStack = Stack(['a', 'b']); numberStack = Stack.of(1, 2); numberOrStringStack = Stack.of('a', 1); // $FlowExpectedError[incompatible-call] numberStack = Stack.of('a', 1); number = Stack([1]).peek(); // $FlowExpectedError[incompatible-type] number = Stack(['a']).peek(); numberStack = Stack([1]).unshift(1); numberOrStringStack = Stack([1]).unshift('a'); // $FlowExpectedError[incompatible-call] numberStack = Stack([1]).unshift('a'); numberStack = Stack([1]).unshiftAll([1]); numberOrStringStack = Stack([1]).unshiftAll(['a']); // $FlowExpectedError[incompatible-call] numberStack = Stack([1]).unshiftAll(['a']); numberStack = Stack.of(1).shift(); // $FlowExpectedError[incompatible-call] numberStack = Stack.of('a').shift(); numberStack = Stack().push(1); numberOrStringStack = Stack([1]).push('a'); // $FlowExpectedError[incompatible-call] numberStack = Stack().push('a'); numberStack = Stack().pushAll([1]); numberOrStringStack = Stack([1]).pushAll(['a']); // $FlowExpectedError[incompatible-call] numberStack = Stack().push(['a']); numberStack = Stack.of(1).pop(); // $FlowExpectedError[incompatible-call] numberStack = Stack.of('a').pop(); numberStack = Stack([1]).withMutations((mutable) => mutable); // $FlowExpectedError[incompatible-call] numberStack = Stack(['a']).withMutations((mutable) => mutable); numberStack = Stack([1]).asMutable(); // $FlowExpectedError[incompatible-call] numberStack = Stack(['a']).asMutable(); numberStack = Stack([1]).asImmutable(); // $FlowExpectedError[incompatible-call] numberStack = Stack(['a']).asImmutable(); numberStack = Stack([1]).map((value, index, iter) => 1); // $FlowExpectedError[incompatible-call] numberStack = Stack([1]).map((value, index, iter) => 'a'); numberStack = Stack([1]).flatMap((value, index, iter) => [1]); // $FlowExpectedError[incompatible-call] numberStack = Stack([1]).flatMap((value, index, iter) => ['a']); numberStack = Stack([1]).flatten(); numberStack = Stack(['a']).flatten(); /* Range & Repeat */ // `{}` provide namespaces { const numberSequence: IndexedSeq<number> = Range(0, 0, 0); } { const numberSequence: IndexedSeq<number> = Repeat(1, 5); } { const stringSequence: IndexedSeq<string> = Repeat('a', 5); } { // $FlowExpectedError[incompatible-call] const stringSequence: IndexedSeq<string> = Repeat(0, 1); } { // $FlowExpectedError[incompatible-type-arg] const stringSequence: IndexedSeq<string> = Range(0, 0, 0); } /* Seq */ let numberSeq = Seq([1, 2, 3]); // $FlowExpectedError[incompatible-type] let numberSeqSize: number = numberSeq.size; let maybeNumberSeqSize: ?number = numberSeq.size; /* Record */ type PersonRecordFields = { age: number, name: string }; type PersonRecord = RecordOf<PersonRecordFields>; const makePersonRecord: RecordFactory<PersonRecordFields> = Record({ age: 900, name: 'Yoda', }); const personRecordInstance: PersonRecord = makePersonRecord({ age: 25 }); { // $FlowExpectedError[incompatible-type] const age: string = personRecordInstance.get('age'); } { // $FlowExpectedError[incompatible-type] const age: string = personRecordInstance.age; } { const age: number = personRecordInstance.get('age'); } { const age: number = personRecordInstance.age; } // $FlowExpectedError[incompatible-call] personRecordInstance.set('invalid', 25); personRecordInstance.set('name', '25'); personRecordInstance.set('age', 33); // FixMe: The first should be FlowExpectedError[incompatible-call], and the second two should be correct, // however all three produce a hard to understand error because there is a bug // with Flow's $Call utility type. // set(personRecordInstance, 'invalid', 25) // set(personRecordInstance, 'name', '25') // set(personRecordInstance, 'age', 33) // Create a Map from a non-prototype "plain" Object let someObj = Object.create(null); someObj.x = 1; someObj.y = 2; let mapOfSomeObj: Map<string, number> = Map(someObj); // $FlowExpectedError[incompatible-call] - someObj is string -> number let mapOfSomeObjMistake: Map<string, string> = Map(someObj); // getIn() type // Deep nested const deepData1: List<Map<string, string>> = List([Map([['apple', 'sauce']])]); const deepNestedString1 = deepData1.getIn([0, 'apple']); { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = deepNestedString1; } { // $FlowExpectedError[incompatible-type] getIn can return undefined const fail: string = deepNestedString1; } { const success: ?string = deepNestedString1; } const listOfListOfNumber: List<?List<?number>> = List([List([1, 2, 3])]); const nestedNum = listOfListOfNumber.getIn([0, 1]); { // $FlowExpectedError[incompatible-type] number is not string const fail: ?string = nestedNum; } { // $FlowExpectedError[incompatible-type] getIn can return undefined const fail: number = nestedNum; } { const success: ?number = nestedNum; } // $FlowExpectedError[incompatible-call] expected a number 1st key listOfListOfNumber.getIn(['whoops', 1]); // $FlowExpectedError[incompatible-call] expected a number 2nd key listOfListOfNumber.getIn([0, 'whoops']); // $FlowExpectedError[incompatible-call] too many keys! listOfListOfNumber.getIn([0, 0, 'whoops']); // Deep nested const deepData: List<Map<string, List<string>>> = List([ Map([['apple', List(['sauce'])]]), ]); const deepNestedString = deepData.getIn([0, 'apple', 0]); { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = deepNestedString; } { // $FlowExpectedError[incompatible-type] getIn can return undefined const fail: string = deepNestedString; } { const success: ?string = deepNestedString; } // $FlowExpectedError[incompatible-call] expected a string 2nd key deepData.getIn([0, 0, 0]); // $FlowExpectedError[incompatible-call] expected a number 3rd key deepData.getIn([0, 'apple', 'whoops']); // Containing Records const listOfPersonRecord: List<PersonRecord> = List([personRecordInstance]); const firstAge = listOfPersonRecord.getIn([0, 'age']); { // $FlowExpectedError[incompatible-type] expected a string key const age: string = firstAge; } { // $FlowExpectedError[incompatible-type] getIn can return undefined const age: number = firstAge; } { const age: ?number = firstAge; } // $FlowExpectedError[incompatible-call] - the first key is not an index listOfPersonRecord.getIn(['wrong', 'age']); // $FlowExpectedError[incompatible-call] - the second key is not an record key listOfPersonRecord.getIn([0, 'mispeld']); // $FlowExpectedError[incompatible-call] - the second key is not an record key listOfPersonRecord.getIn([0, 0]); // $FlowExpectedError[incompatible-call] listOfPersonRecord.setIn([0, 'age'], 'Thirteen'); listOfPersonRecord.setIn([0, 'age'], 13); // $FlowExpectedError[prop-missing] listOfPersonRecord.updateIn([0, 'age'], (value) => value.unknownFunction()); listOfPersonRecord.updateIn([0, 'age'], (value) => value + 1); listOfPersonRecord.updateIn([0, 'age'], 0, (value) => value + 1); // Recursive Records type PersonRecord2Fields = { name: string, friends: List<PersonRecord2> }; type PersonRecord2 = RecordOf<PersonRecord2Fields>; const makePersonRecord2: RecordFactory<PersonRecord2Fields> = Record({ name: 'Adam', friends: List(), }); const friendly: PersonRecord2 = makePersonRecord2(); { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = friendly.getIn(['friends', 0, 'name']); } // notSetValue provided { const success: string = friendly.getIn(['friends', 0, 'name'], 'Abbie'); } { const success: ?string = friendly.getIn(['friends', 0, 'name']); } // Functional API { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = getIn(friendly, ['friends', 0, 'name']); } // notSetValue provided { const success: string = getIn(friendly, ['friends', 0, 'name'], 'Abbie'); } { const success: ?string = getIn(friendly, ['friends', 0, 'name']); } // Deep nested containing recursive Records const friendlies: List<PersonRecord2> = List([makePersonRecord2()]); { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = friendlies.getIn([0, 'friends', 0, 'name']); } // notSetValue provided { const success: string = friendlies.getIn([0, 'friends', 0, 'name'], 'Abbie'); } { const success: ?string = friendlies.getIn([0, 'friends', 0, 'name']); } // $FlowExpectedError[incompatible-call] friendlies.setIn([0, 'friends', 0, 'name'], 123); friendlies.setIn([0, 'friends', 0, 'name'], 'Sally'); friendlies.updateIn([0, 'friends', 0, 'name'], (value) => // $FlowExpectedError[prop-missing] value.unknownFunction() ); friendlies.updateIn([0, 'friends', 0, 'name'], (value) => value.toUpperCase()); friendlies.updateIn([0, 'friends', 0, 'name'], 'Unknown Name', (value) => value.toUpperCase() ); // Nested plain JS values type PlainPerson = { name: string, friends: Array<PlainPerson> }; const plainFriendly: PlainPerson = { name: 'Bobbie', friends: [] }; const plainFriendlies: List<PlainPerson> = List([plainFriendly]); { // $FlowExpectedError[incompatible-call] 'fraaands' is an unknown key in PlainPerson const fail: ?number = plainFriendlies.getIn([0, 'fraaands', 0, 'name']); } { // $FlowExpectedError[incompatible-call] 0 is an unknown key in PlainPerson const fail: ?number = plainFriendlies.getIn([0, 'fraaands', 0, 0]); } { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = plainFriendlies.getIn([0, 'friends', 0, 'name']); } { // $FlowExpectedError[incompatible-type] can return undefined const fail: string = plainFriendlies.getIn([0, 'friends', 0, 'name']); } { const success: ?string = plainFriendlies.getIn([0, 'friends', 0, 'name']); } // $FlowExpectedError[incompatible-call] number is not a string plainFriendlies.setIn([0, 'friends', 0, 'name'], 123); plainFriendlies.setIn([0, 'friends', 0, 'name'], 'Morgan'); plainFriendlies.updateIn([0, 'friends', 0, 'name'], (value) => // $FlowExpectedError[prop-missing] value is a string, this is an unknown function value.unknownFunction() ); plainFriendlies.updateIn([0, 'friends', 0, 'name'], (value) => value.toUpperCase() ); // $FlowExpectedError[incompatible-call] number is not a string plainFriendlies.updateIn([0, 'friends', 0, 'name'], () => 123); plainFriendlies.updateIn([0, 'friends', 0, 'name'], () => 'Whitney'); // Functional API { // $FlowExpectedError[incompatible-call] 'fraaands' is an unknown key in PlainPerson const fail: ?number = getIn(plainFriendlies, [0, 'fraaands', 0, 'name']); } { // $FlowExpectedError[incompatible-call] 0 is an unknown key in PlainPerson const fail: ?number = getIn(plainFriendlies, [0, 'fraaands', 0, 0]); } { // $FlowExpectedError[incompatible-type] string is not a number const fail: ?number = getIn(plainFriendlies, [0, 'friends', 0, 'name']); } { // $FlowExpectedError[incompatible-type] can return undefined const fail: string = getIn(plainFriendlies, [0, 'friends', 0, 'name']); } { const success: ?string = getIn(plainFriendlies, [0, 'friends', 0, 'name']); } // $FlowExpectedError[incompatible-call] number is not a string setIn(plainFriendlies, [0, 'friends', 0, 'name'], 123); setIn(plainFriendlies, [0, 'friends', 0, 'name'], 'Morgan'); updateIn(plainFriendlies, [0, 'friends', 0, 'name'], (value) => // $FlowExpectedError[prop-missing] value is a string, this is an unknown function value.unknownFunction() ); updateIn(plainFriendlies, [0, 'friends', 0, 'name'], (value) => value.toUpperCase() ); // $FlowExpectedError[incompatible-call] number is not a string updateIn(plainFriendlies, [0, 'friends', 0, 'name'], () => 123); updateIn(plainFriendlies, [0, 'friends', 0, 'name'], () => 'Whitney'); // Plain JS values { const success: number | void = get([1, 2, 3], 0); } { const success: number | string = get([1, 2, 3], 0, 'missing'); } { // $FlowExpectedError[incompatible-call] - string is not an array index const success: number = get([1, 2, 3], 'z'); } // Note: does not return null since x is known to exist in {x,y} { const success: number = get({ x: 10, y: 10 }, 'x'); } { // $FlowExpectedError[incompatible-call] - z is not in {x,y} const success: number | void = get({ x: 10, y: 10 }, 'z'); } { const objMap: { [string]: number } = { x: 10, y: 10 }; const success: number | void = get(objMap, 'z'); } { const success: number = get({ x: 10, y: 10 }, 'x', 'missing'); } { const objMap: { [string]: number } = { x: 10, y: 10 }; const success: number | string = get(objMap, 'z', 'missing'); } // Deeply nested records type DeepNestFields = { foo: number, }; type DeepNest = RecordOf<DeepNestFields>; const deepNest: RecordFactory<DeepNestFields> = Record({ foo: 0, }); type NestFields = { deepNest: DeepNest, }; type Nest = RecordOf<NestFields>; const nest: RecordFactory<NestFields> = Record({ deepNest: deepNest(), }); type StateFields = { nest: Nest, }; type State = RecordOf<StateFields>; const initialState: RecordFactory<StateFields> = Record({ nest: nest(), }); const state = initialState(); (state.setIn(['nest', 'deepNest', 'foo'], 5): State); // $FlowExpectedError[incompatible-call] (state.setIn(['nest', 'deepNest', 'foo'], 'string'): State); // $FlowExpectedError[incompatible-call] (state.setIn(['nest', 'deepNest', 'unknownField'], 5): State);