0

I need to access only the "departments" type in this large type generated from GraphQL:

export type GetCompanyChartQuery = (
  { __typename?: 'Query' }
  & { generateOrgChart?: Maybe<(
    { __typename?: 'DepartmentNode' }
    & Pick<DepartmentNode, 'name'>
    & { manager?: Maybe<(
      { __typename?: 'EmployeeNode' }
      & Pick<EmployeeNode, 'name' | 'mobilePhone'>
    )>, departments?: Maybe<Array<Maybe<(
      { __typename?: 'DepartmentNode' }
      & Pick<DepartmentNode, 'name' | 'depth'>
      & { manager?: Maybe<(
        { __typename?: 'EmployeeNode' }
        & Pick<EmployeeNode, 'name'>
      )>, employees?: Maybe<Array<Maybe<(
        { __typename?: 'EmployeeNode' }
        & Pick<EmployeeNode, 'imageUrl' | 'mobilePhone' | 'name' | 'position' | 'title' | 'depth'>
      )>>>, departments?: Maybe<Array<Maybe<(
        { __typename?: 'DepartmentNode' }
        & Pick<DepartmentNode, 'name' | 'depth'>
        & { manager?: Maybe<(
          { __typename?: 'EmployeeNode' }
          & Pick<EmployeeNode, 'name'>
        )>, employees?: Maybe<Array<Maybe<(
          { __typename?: 'EmployeeNode' }
          & Pick<EmployeeNode, 'imageUrl' | 'mobilePhone' | 'name' | 'position' | 'title' | 'depth'>
        )>>> }
      )>>> }
    )>>> }
  )> }
);

I cannot find a way around this. Pick<GetCompanyChartQuery, 'subType'> or GetCompanyChartQuery['subtype'] wont do the trick here.

I am trying to fetch data with a GraphQL query and put the response in a state like this:

const [departments, setDepartments] = useState<TheTypeINeedToAccess>();

setDepartments(data?.generateOrgChart?.departments);

But to do this I need the correct type.

Thanks in advance.

2 Answers 2

0

I think the issue with picking the subtypes is the optional properties. If you make the object non-nullish, TypeScript can pick out the subtype.

type Departments = Required<GetCompanyChartQuery>["generateOrgChart"]["departments"]
Sign up to request clarification or add additional context in comments.

Comments

0

I ended up using this code from this answer.

It even works with arrays and optional properties.

type DeepPick<T, K extends string> = T extends object ? {
  [P in Head<K> & keyof T]: T[P] extends readonly unknown[] ? DeepPick<T[P][number], Tail<Extract<K, `${P}.${string}`>>>[] : DeepPick<T[P], Tail<Extract<K, `${P}.${string}`>>>
} : T
type Head<T extends string> = T extends `${infer First}.${string}` ? First : T;
type Tail<T extends string> = T extends `${string}.${infer Rest}` ? Rest : never;

Usage example:

interface TestBook {
  id: string;
  name: string;
}

interface TestUser {
  id: string;
  email: string;
  books: TestBook[];
  book: TestBook,
}

type T = DeepPick<TestUser, "id" | "books.name" | "book.id">;
//T = {
//  id: string;
//  books: {
//    name: string;
//  }[];
//  book: {
//    id: string;
//  };
//}

Playground

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.