8000 Various flowtype issues with Map and OrderedMap · Issue #1029 · immutable-js/immutable-js · GitHub
[go: up one dir, main page]

Skip to content

Various flowtype issues with Map and OrderedMap #1029

@howardjing

Description

@howardjing

In the process of working on #1027, I found several flowtype inconsistencies. Some of these are easy fixes, others seem more complicated -- I can submit a PR to address some of these issues.

Inconsistent Map / OrderedMap constructor behavior

This gives an error:

// $ExpectError
stringToNumber = Map([['a', 'b']])

Whereas this does not:

// FIXME: this should trigger an error -- this is actually a Map<string, string>
stringToNumber = Map(List.of(List(['a', 'b'])))

I'm not sure how easy this is to fix.

Map / OrderedMap mergeWith definition is incorrect:

flow:

mergeWith<K_,W,X>(
  merger: (previous: V, next: W, key: number) => X,
  ...iterables: ESIterable<W>[]
): Map<K,V|W|X>;

typescript:

mergeWith(
  merger: (previous: V, next: V, key: K) => V,
  ...iterables: Iterable<K, V>[]
): Map<K, V>;

Note that in the flow definitions, key is a number, and an iterable is an array like object, whereas in the typescript definitions, key is of type K and an iterable is a map like object.

I can submit a PR for this.

Map / OrderedMap updateIn definition is incorrect:

flow:

updateIn(keyPath: ESIterable<any>, notSetValue: any, value: any): Map<K,V>;
updateIn(keyPath: ESIterable<any>, value: any): Map<K,V>;

typescript:

updateIn(
  keyPath: Array<any>,
  updater: (value: any) => any
): Map<K, V>;
updateIn(
  keyPath: Array<any>,
  notSetValue: any,
  updater: (value: any) => any
): Map<K, V>;

Note that the updater argument in flow is typed incorrectly.

I can submit a PR for this.

Map / OrderedMap flatMap weirdness

I expected this test to throw an error, but it did not:

/**
 * FIXME: this should throw an error, it's an OrderedMap<string, string>
 */
orderedStringToNumber = OrderedMap({'a': 1}).flatMap((v, k) => (OrderedMap({ [k]: 'a' })))

Not really sure what's going on there, but I can probably look into.

Flowtype definitions are looser than typescript definitions

This is more of an observation than an issue. Methods in the flowtype definitions that persist changes are allowed to introduce new types to data structures, whereas the same is not true of the typescript definitions. For example, this is the Set#add method in flow:

class Set<T> {
  add<U>(value: U): Set<T|U>;
}

and this is the Set#add method in typescript:

interface Set<T> {
  add(value: T): Set<T>;
}

So we can do the following in flow

Set([1]).add('a');

but not in typescript. The above is also valid behavior in plain javascript for what it's worth, so the flowtype behavior seems closer to the javascript behavior than the typescript behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0