1

I have following four types

Type T1

export type T1 = "p" | "q" | "r" | "a" | "b";

Type T2

export type T2 = {
  h: string;
  hc: {};
};

Interface Def

export interface Def {
  [k: string]: {
    [K in T1 | "abc"]?: K extends T1
      ? T2
      : {
          [k in T1]?: T2;
        };
  };
}

Interface A

export interface A {
  name: string;
  def: Def;
}

The usage should be like follows

const x: A = {
  name: "test",
  def: {
    xxx: {
      p: {
        h: "s",
        hc: {
         
        },
      },
      abc: {
        p: {
          h: "s",
          hc: {
            
          },
        },
        abc: {
          p: {
            h: "s",
            hc: {
              
            },
          },
        },
      },
    },
  },
}; 

The problem I am having is that if the object of type Def with in attribute xxx has property abc then it should recursively accept the abc object again as above example. I tried calling Def recursively but that does not work.

2
  • Is this approach what you're looking for? If so I can write up an answer explaining; if not, what am I missing? Commented Oct 23, 2022 at 18:42
  • Hey @jcalz string | string is a mistake it should be string. and your solution is what I was looking for. Thanks :) Commented Oct 31, 2022 at 9:26

1 Answer 1

1

I would suggest writing Def like

interface Def {
  [k: string]: DefEntry
}

where DefEntry is a recursive object type:

type DefEntry =
  { [K in T1]?: T2 } & // this is equivalent to Partial<Record<T1, T2>>
  { abc?: DefEntry };

or, equivalently, you could write DefEntry as a recursive interface like

interface DefEntry extends Partial<Record<T1, T2>> {
  abc?: DefEntry
}

In neither case is conditional types like K extends T1 ? T2 : ... necessary.


And that makes your A interface and the test value work as desired:

const x: A = { // okay
  name: "test",
  def: {
    xxx: {
      p: { h: "s", hc: {}, },
      abc: {
        p: { h: "s", hc: {}, },
        abc: {
          p: { h: "s", hc: {}, },
        },
      },
    },
  },
}; 

Playground link to code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.