Home > Blockchain >  Nested keyof keyof T in Typescript
Nested keyof keyof T in Typescript

Time:02-26

I have an interface like this...

export interface IMyInterface {
  test1: {
    test1Sub: {
      test1SubSub: string
    }
  },
  test2: {
    test2Sub: {
      test2SubSub: string
    }
  }
}

I would like to be able to strongly type the names of the nested levels into a generic function to give TypeScript intellisense something like this which is in a generic class passing in Type T.

  getSetting = (level1: keyof T, level2: keyof keyof T) => {
    console.log(level1, level2)
  }

Is this possible? How I have it at the moment it gives me this warning, it works fine for 'test1' but not 'test1Sub;

settings.getPageSettings('test1', 'test1Sub')

Argument of type '"test1Sub"' is not assignable to parameter of type '"toString" | "valueOf" | "toLocaleString"'

CodePudding user response:

You don't want keyof keyof for the sub-level as this will the the keys of each type defined by keyof IMyInterface, instead you want keyof T[K]

Here's a quick playground.

export interface IMyInterface {
  test1: {
    test1Sub: {
      test1SubSub: string
    }
  },
  test2: {
    test2Sub: {
      test2SubSub: string
    }
  }
}

function getSetting<T extends IMyInterface, K extends keyof T>(level1: K, level2: keyof T[K]) {
    console.log(level1, level2)
  }


// usage
const myInterface:IMyInterface ={
  test1: {
    test1Sub: {
      test1SubSub: 'subsub1'
    }
  },
  test2: {
    test2Sub: {
      test2SubSub: 'subsub2'
    }
  }
}

getSetting('test1', 'test1Sub');

getSetting('test2', 'test1Sub');
//                   ^^^^^^^^
// Argument of type '"test1Sub"' is not assignable to parameter of type '"test2Sub"'
  • Related