Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply TS 2.1 keyof & mapped types #119

Closed
wclr opened this issue Dec 10, 2016 · 5 comments
Closed

Apply TS 2.1 keyof & mapped types #119

wclr opened this issue Dec 10, 2016 · 5 comments

Comments

@wclr
Copy link
Contributor

wclr commented Dec 10, 2016

TS 2.1 now supports keyof operator and mapped types
https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#keyof-and-lookup-types

It would be useful to type different methods like prop, lens, etc

@KiaraGrouwstra
Copy link
Member

Thanks! I've now tried to use these in assoc, dissoc, map, mapObjIndexed, pick, pluck, project, prop, propIs, propEq, propOr, propSatisfies, and a failed/WIP attempt at path. I've been talking to donnut and blakeembrey, and hopefully we'll manage an NPM release soon.

Now lenses are a bit tough. Since you brought them up, I tried to expand on typings there, but I'm not sure yet how I can use keyof there, and I'm open to input there. The issue pertains order of generics/information, and this is one of the great general challenges in typescript-ramda. Let's say we wanted to type a lens such as to make use of this:

    interface KeyLens<K extends keyof T> {
        <T extends Struct<any>>(obj: T): T[K]; // get
        <T extends Struct<any>>set(v: T[K], obj: T): T;
        // <T extends Struct<any>>map(fn: (v: T[K]) => T[K], obj: T): T
    }

The main issue here is of course, such a lens is actually generic, in the sense it's agnostic toward the actual data structure it might be applied to. We'd like to be able to define such a lens just by the key it navigates to, but if we wish to apply keyof there, we run into a problem: the object structure T is not defined yet at this point.

Alternatively, we can add this T in the interface generics already, before K, and hope TS will take our word for the fact this will hold for any given T.
I made a PoC for this, but unfortunately, TS doesn't appear to like this reasoning. I tries to evaluate things instead of lazily keeping our options open, and as a result, ends up discarding this option entirely.

There might be a way to improve on that, but I'm not sure if it could work in the current state of TS.
I'll close for the moment as I think I've handled anything actionable as of now. This doesn't mean I'm not looking for further suggestions to improve here though -- to the contrary!

@wclr
Copy link
Contributor Author

wclr commented Dec 10, 2016

@tycho01
This is how path can be typed: microsoft/TypeScript#12290

@KiaraGrouwstra
Copy link
Member

Whoa, that's awesome, thank you! 😄 It evidently did better than my threads on path there...
I think I can make versions out of that for different path lengths; that should help.
As it stands it appears unable to deal with navigation of arrays though, as [K1 in A] notation apparently demands strings. I may want to ask them for ideas on that...

@jcristovao
Copy link
Collaborator

jcristovao commented Jan 30, 2017

Hello :)

I'm clearly struggling understanding this new syntax...

Example:

import R from "ramda";

interface Car {
  wheels: number;
  doors: number;
};

type carKeys = keyof Car;

interface FakeCar {
  wheels: number;
};

type fakeCarKeys = keyof FakeCar;

const car: Car = { wheels: 4, doors: 5 };

const fakeCar: FakeCar = R.pick<Car, fakeCarKeys>(["wheels"], car);

console.log(fakeCar);

This get's me:

error TS2536: Type '0' cannot be used to index type 'T'

What should I use as the second parameter of <,> (if type inference is failing me)?

EDIT: nevermind, the problem is not on my code, but here. A bug?

@KiaraGrouwstra
Copy link
Member

Hey, this appears to be the regression described in #129. I haven't had the time to test their fix though... if the new nightly works we can just update it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants