0

I want to create a function that you can give a list of object keys and it would navigate through those keys on the object you pass and return the value or undefined if it doesn't exist and infer the correct type based on the type of the object passed in.

Here's how it should work:

prop(['one', 'two', 'three'], {one: {two: {three: 'found it!'}}}) === 'found it!'
prop(['one', 'two', 'four'], {one: {two: {three: 'found it!'}}}) === undefined

I've had a go at typing it specifically with 3 levels here but want it to work with any reasonable depth in the end. Here's where I got to so far, see it with TS errors here :

function prop<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(keys: [K1, K2, K3], obj: T) {
  // I don't think this type is right but can't find a way to get it to understand what level it's currently at
  let currentDepth: T | T[K1] | T[K1][K2] = obj;
  for (let i = 0; i < keys.length; i++) {
    const k = keys[i]
    currentDepth = currentDepth[k];
    if (i === keys.length - 1) {
      return currentDepth;
    }
    if (typeof currentDepth === 'undefined') {
      return currentDepth
    }
  }
  return undefined
}

Any hints about whether is possible or other approaches appreciated. Thanks

2
  • You might need to implement it recursively. Having that large union type and iteratively accessing nested properties is not really type-safe at all. Commented Dec 11, 2018 at 16:57
  • 1
    Possible duplicate of TypeScript: Get deeply nested property value using array Commented Dec 11, 2018 at 19:11

0

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.