Home > Mobile >  How to infer deep object?
How to infer deep object?

Time:05-27

Let's say I have an object that looks like this

const myObj = {
    homePage: ["on", {
        title: 'Home Page',
    }]
})

I want to restrict object values but infer keys. I saw another SO that resolves my problem (partially)

export type OnOffFormat = "off" | "on";
export type AcceptedValue = string | number | boolean;
export type ArrayFormat = [OnOffFormat] | [OnOffFormat, Record<string, AcceptedValue>]
export type RuleFormat = OnOffFormat | ArrayFormat

const asParsedConfig = <T, Z>(config: { [K in keyof T]: OnOffFormat | [OnOffFormat, {
    [TK in keyof Z]: AcceptedValue;
} ]}) => config;

export const myObj = asParsedConfig({
    homePage: ["on", {
        title: 'Home page',
    }]
})

The problem is, when I try to check myObj.homePage[1] TypeScript does not recognize its keys and values enter image description here

As you can see, second is inferred as {} instead of { title: "Home Page" }

Do you know how I can do to infer its config ? Thanks !

CodePudding user response:

You need to structure your generics in a different way. Start with the innermost, and simplest type (AcceptedValue) and then go up layer by layer. This will work:

type OnOffFormat = "off" | "on";
type AcceptedValue = string | number | boolean;

const asParsedConfig = <
  Value extends AcceptedValue,
  R extends Record<string, Value>,
  Config extends Record<string, OnOffFormat | [OnOffFormat, R]>,
>(config: Config) => config;

const myObj = asParsedConfig({
    homePage: ["on", {
        title: 'Home page',
    }]
});

const second = myObj.homePage[1];

Variable second will have the type you want.

  • Related