Reputation: 163
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
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 !
Upvotes: 0
Views: 442
Reputation: 1174
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.
Upvotes: 2