1

This works fine for mapping deep keys of objects:

type Car = {
  color: string;
  model: {
     name: string;
  }
}

export type DeepKey<T> = {
   [P in keyof T]: DeepKey<T[P]>;
}

const car: DeepKey<Car> = {};
car.model.name // is ok

But how to make it a chain of functions like this:

car("model")("name")

Something like:

export type DeepFunc<T> = (k: [P in keyof T]) => DeepFunc<T[P]>;

Another solution could be maybe array of keys like this. (But the function way is interesting too)

["model", "name"] or ["color"]
5
  • What's the point of DeepKey<Car>, vs. just using Car? And in the latter example, how is that actually implemented at runtime, let alone in typing, how does it know when you want the actual value rather than a wrapper function for the next layer? Commented Jun 10, 2020 at 16:02
  • Point is to make the typesafe tool to get the key path of the Car object. Like here: reddit.com/r/typescript/comments/dt0wzx/… problem is, this doesn't work on IE because it is based on Proxy with "all catch getter". So I was thinking to rewrite it to functional form which could work then. Commented Jun 10, 2020 at 16:05
  • I don't want the value but at the end extract the whole path to be used for dot notation like "model.name". This is how works the deep keys on the reddit link above. But i need it as functions Commented Jun 10, 2020 at 16:09
  • @luky is your goal to be able to have a function similar to path in ramda? Commented Jun 10, 2020 at 16:23
  • yes that is one possible solution Commented Jun 10, 2020 at 16:40

1 Answer 1

3

You can type a function that does this, your solution is pretty close, but the function generic be generic:

export type DeepFunc<T> = <K extends keyof T>(k: K) => DeepFunc<T[K]>;
type Car = {
  color: string;
  model: {
     name: string;
  }
}
declare var car: DeepFunc<Car>
car("model")("name")
car("model")("name2") // err

Playground Link

Just keep in mind that since the ?. operator appeared the need for safe access function has decreased (at least with respect to guarding for null and undefined)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.