facebook / facebook/flow

Ramda.assoc cannot be typed correctly

Open
#4,748 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
22.3k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

[`Ramda.assoc()`](http://ramdajs.com/docs/#dissoc), by analogy with Clojure's `assoc`, takes a key, a value, and an object, and returns a copy of the object with that key and value added. (Ramda functions are also curried, but that's orthogonal to this issue.)

The most reasonable way to type `assoc()` I could come up with is the following, which doesn't work correctly:

```js
declare function assoc(key: K, val: V, src: O): O & { [K]: V };

let assocd = assoc('a', 'one', { b: 2 });
(assocd.a: string);
(assocd.b: number);
// This should be an error, but it's not, because the type of `assocd` now has
// an indexer property `{[string]: string}`.
(assocd.foo: string);
```

It appears that `K` becomes bound to `string`, and not the more specific type `'a'`. Notice that constraining `K` to `'a'` fixes the problem:

```js
declare function assoc(key: K, val: V, src: O): O & { [K]: V };

let assocd = assoc('a', 'one', { b: 2 });
(assocd.a: string);
(assocd.b: number);
// $ExpectError: This is now an error, because the type of `assocd` no longer
// uses an indexer property.
(assocd.foo: string);
```

I'm not certain where or if there's a shortcoming in Flow here, but it would be nice to be able to type `assoc` properly.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.