Search code examples
typescripttypesnested

TypeScript: Get type from a nested type


I have a type (Note: Both a and foo can be optional):

type Something = {
  a?: {
    foo?: {
      bar: {
        c: {
          id: string,
          countryCode: number,
          animal: { ... }
        }
      }
    }
  }
}

Now I want to have another type MyType, which is bar in the example above. So MyType will be:

type MyType = {
  c: {
    id: string,
    countryCode: number,
    animal: { ... }
  }
}

My question: How could I create MyType from type Something?

Update: See this comment for the answer: TypeScript: Get type from a nested type


Solution

  • The easiest way would be: type MyType = NonNullable<NonNullable<Something["a"]>["foo"]>["bar"];

    However, I can suggest a more dynamic approach as well:

    type Something = {
      a?: {
        foo?: {
          bar: {
            c: {
              id: string;
              countryCode: number;
            };
          };
        };
      };
    };
    
    type RetrieveSubProperty<T, K extends string[]> = [] extends K
      ? T
      : K extends [infer First extends keyof T, ...infer Rest extends string[]]
      ? RetrieveSubProperty<NonNullable<T[First]>, Rest>
      : never;
    
    type Bar = RetrieveSubProperty<Something, ["a", "foo", "bar"]>;
    

    playground