«Любой» тип данных для GraphQL Query Return Type - PullRequest
1 голос
/ 24 марта 2020

Я немного новичок в Typescript и у меня есть некоторые проблемы с типами данных. Мне сказали, что я должен избегать использования любого типа данных, поскольку это сводит на нет весь смысл использования Typescript. Однако я не могу изменить типы данных. Например,

, когда я запускаю запрос GraphQL, я использую это:

   login({
      variables: {
        email: email,
        password: password,
      },
    })
      .then(({ data }: any) => {
        localStorage.setItem('token', data.loginEmail.accessToken);
        setShouldRedirect(true);
        //props.history.push("/panel");
      })

data.loginEmail.accessToken - это строка, поэтому я изменил :any на строку, но я получаю ошибки, которые:

Argument of type '({ data }: string) => void' is not assignable to parameter of type '(value: ExecutionResult<any>) => void | PromiseLike<void>'.
  Types of parameters '__0' and 'value' are incompatible.
    Type 'ExecutionResult<any>' is not assignable to type 'string'.  TS2345

Если я изменю тип на object, я получу Property 'data' does not exist on type '{}'. TS2339, но в документации также сказано, что мутация возвращает объект. Так что, если не объект или строка, как еще можно указать тип данных для такого объекта? Это вообще возможно?

Точно так же, когда я сопоставляю такие элементы после запроса:

{data &&
          data.users.nodes &&
          data.users.nodes.map((c: any, i: any) => (
            <li key={i}>
              Id: {c.id}, First Name: {c.firstName}, Last Name: {c.lastName},
              Email: {c.email}, phoneNumber: {c.phoneNumber}
            </li>
          ))}

Как еще можно указать c и я? Там нет простой целочисленной опции для i.

Редактировать:

Схема:

  loginEmail(
    email: String!
    password: String!
  ): SignInResponse!
type SignInResponse {
  accessToken: String!
}

Код GraphQL:

export type MutationLoginEmailArgs = {
  email: Scalars['String'],
  password: Scalars['String']
};

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

Похоже, что ваша структура данных соответствует интерфейсу следующего типа:

interface MyDataReponse {
  users: {
   nodes: {
    id: string; // maybe this is number in your case
    firstName:string;
    lastName: string;
    phoneNumber: string;
    email: string;
   }[]
  }
}

Тогда по вашим данным:

.then(({ data }: ExecutionResult<{data:MyDataReponse;}>) => {
0 голосов
/ 24 марта 2020

Если вы используете TypeScript, вы должны сгенерировать типы как для данных, возвращаемых ловушкой, так и для переменных, которые вы передаете ей. Генерация типов может быть выполнена с использованием Apollo CLI или GraphQL Code Generator .

После того, как вы получили ваши типы, вы можете использовать их со своими хуками в качестве показано здесь, в документах . Делая это, вы избежите необходимости явно назначать типы при использовании свойства data, возвращаемого ловушкой. Вы также добавите безопасность типов для любых переменных, передаваемых в ловушку.

Пример использования из документов:

interface RocketInventory {
  id: number;
  model: string;
  year: number;
  stock: number;
}

interface RocketInventoryData {
  rocketInventory: RocketInventory[];
}

interface RocketInventoryVars {
  year: number;
}

const GET_ROCKET_INVENTORY = gql`
  query getRocketInventory($year: Int!) {
    rocketInventory(year: $year) {
      id
      model
      year
      stock
    }
  }
`;

export const SomeComponent = () => {
  const { loading, data } = useQuery<RocketInventoryData, RocketInventoryVars>(
    GET_ROCKET_INVENTORY,
    { variables: { year: 2019 } }
  );
  ...
}
...