Open Inhye-Cheong opened 2 years ago
Mostly we hear complaints about that, and have to point them to the DefinitelyTyped folks who maintain the TS typings.
So by the same token, all credit must go to them.
There is an effort underway to move them in-house, but it's not moving quickly.
@CrossEye
First of all, thanks for the reply.
I'm not using ramda heavily, so I didn't have any "complaints" about type inference as you described.
My question was, How does ramda
do better type inference than js built-in functions
?
For example,
import * as R from 'ramda';
const MOCK_DATA = {
'first-key': 'this is first value',
'second-key': 'this is second value',
}
// using ramda : The type inference of the `key` is correct.
const findKeyUsingRamda = (label: string) => R.keys(MOCK_DATA).find((key) => MOCK_DATA[key] === label);
// using js built-in functions : The type of `key` cannot be inferred.
const findKey = (label: string) => Object.keys(MOCK_DATA).find((key) => MOCK_DATA[key] === label);
~~~~~~~~~~~~~~ Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ 'first-key': string; 'second-key': string; }'.
No index signature with a parameter of type 'string' was found on type '{ 'first-key': string; 'second-key': string; }'.ts(7053)
I know very little about TS typings, nor how these were implemented in DefinitelyTyped for Ramda. But if I were to hazard a guess, then I would expect that the type assigned to R.keys
is something like "a function from an Object to an array of Strings" and the one assigned to Object .keys
is more like "a function from an Object to a mixed array of Strings and Symbols."
I'm sure this can be looked up, and while I know I could find the Ramda
version, I don't know where to look for the Object.prototype
one.
Of course that more generic one should also apply to Ramda's keys
as well, but I'm guessing the TS implementers took some signals from Ramda's Hindley-Milner-inspired types, and treat some of the signatures as more aspirational than pedantic.
The main difference is that Ramda leverages a combination of generics and keyof operator while native Object.prototype.keys
always returns array of strings.
@CrossEye
"a function from an Object to an array of Strings"
Looking at the implementation it goes even one step further - "a function from an Object to an array of Object keys" - which means that it returns a union containing each key:
export function keys<T extends object>(x: T): Array<keyof T>;
While Object.prototype.keys
:
keys(o: object): string[];
Because Object.prototype.keys
returns array of any strings TS can't determine what type is MOCK_DATA[key]
going to be - while when called using Ramda it can guarantee that key
will be a key of MOCK_DATA
and therefore assume its type.
Hello. I am a front-end developer who enjoys using
ramda
(+@types/ramda
) +typescript
. When using ramda, the type inference of typescript is often much better than using js built-in functions.ex) Object.keys etc.
So, suddenly, a question arose. Can you explain why type inference works so well with ramda? FYI, I'm not a user who knows even the deep stuff of fp-ts, monad, functor, etc.