1

Given an interface like this:

interface Theme {
    color: {
        red: string;
        blue: string;
    };
    fontFamily: {
        heavy: string;
        light: string;
    };
}

I would like to create a type that represents a valid property path in that interface.

i.e. something that would prevent compilation if I wrote an invalid path.

type ValidThemePathString = <insert solution here>;

const path1: ValidThemePathString = 'color.red'; // good
const path2: ValidThemePathString = 'color.green'; // compiler error
const path3: ValidThemePathString = 'fontFamily.red'; // compiler error

If this is not possible to achieve as a string through template literals, a tuple would be just as good

const path1: ValidThemePathTuple = ['color','red']; // good
const path2: ValidThemePathTuple = ['color', 'green']; // compiler error
const path3: ValidThemePathTuple = ['fontFamily', 'red']; // compiler error

Especially if the solution can provide hints to an IDE about what the next valid path part could be based on what has come previously in the tuple (narrowing down the options)

I only need this to work 2 levels deep if that helps

The best I've been able to come up with so far is a helper like this:

const path = <LevelOne extends keyof Theme, LevelTwo extends keyof Theme[LevelOne]>(
    levelOne: LevelOne,
    levelTwo: LevelTwo,
) => [levelOne, levelTwo];

const path1: ValidThemePathTuple = path('color','red'); // good
const path2: ValidThemePathTuple = path('color', 'green'); // compiler error
const path3: ValidThemePathTuple = path('fontFamily', 'red'); // compiler error

It feels like this should be possible without a helper, but I just haven't been able to make it work

Thanks in advance for any ideas

EDIT: If you're scanning this, the following link in a comment from @jcalz below is what you're looking for: here

Pend
  • 662
  • 7
  • 12
  • 1
    See the linked q/a for information. If I use the `Leaves` definition from there I get [this code](https://tsplay.dev/weXpaW). – jcalz Apr 08 '22 at 02:28
  • 1
    thank-you very much. I had seen that answer but to be honest I struggled to parse it without an example of it in use/was not at all sure it was what I was after. Thank-you for your example! – Pend Apr 08 '22 at 02:33
  • You might find [this utility from type-fest](https://github.com/sindresorhus/type-fest/blob/main/source/get.d.ts) useful. – Amiratak88 Apr 08 '22 at 02:42

0 Answers0