Open Peeja opened 7 years ago
Interestingly, a generic does appear to be able to get a literal type. For instance:
declare function foo <T>(a: T): {foo: T};
(foo('a'): {foo: 'a'});
// $ExpectError: `T` is bound to the literal type `'a'`, so the return value is known to be `{foo: 'a'}`.
(foo('a'): {foo: 'b'});
But, the other way around:
declare function bar <T>(a: T): {[T]: 'bar'};
(bar('a'): {a: 'bar'});
// This passes, but should fail. Flow does not require the property to be `'a'`.
(bar('a'): {b: 'bar'});
As before, bounding T to the literal 'a'
makes it work for this specific case:
declare function bar <T: 'a'>(a: T): {[T]: 'bar'};
(bar('a'): {a: 'bar'});
// $ExpectError: The property is correctly required to be the literal `'a'`.
(bar('a'): {b: 'bar'});
So, while a generic can take a literal type, using it in an indexer property appears to force it to a primitive type, unless the generic is bounded so that that's not possible.
Ramda.assoc()
, by analogy with Clojure'sassoc
, 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:It appears that
K
becomes bound tostring
, and not the more specific type'a'
. Notice that constrainingK
to'a'
fixes the problem: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.