The following code compiles:
type Ugh = {
boo: {[s: string]: Ugh },
baz: ({ [P in keyof Ugh["boo"]]: Ugh["boo"][P] extends Ugh ? Ugh["boo"][P] : string })
};
const q: Ugh = { boo: {}, baz: {}};
const v: Ugh = {boo: { why: { boo: {}, baz: {}}}, baz: { why: { boo: {}, baz: {}} }};
whereas the following doesn't
type Ugh = {
boo: {[s: string]: string | Ugh },
baz: ({ [P in keyof Ugh["boo"]]: Ugh["boo"][P] extends Ugh ? Ugh["boo"][P] : string })
};
const q: Ugh = { boo: {}, baz: {}};
const v: Ugh = {boo: { why: { boo: {}, baz: {}}}, baz: { why: { boo: {}, baz: {}} }};
The only difference is in the type of boo. Why doesn't the second one compile?
type Ugh = { boo: { [s: string]: Ugh; }; baz: { [x: string]: Ugh; }; }; concrete conditional types will be eagerly evaluated. If you can explain your use case somewhere maybe we can suggest a type that works for what you're trying to do. It is likely that you will have to makeUghgeneric.