简体   繁体   中英

"Any" data type for GraphQL Query Return Type

I am a bit new to Typescript and am having some issues with data types. I was told that I should avoid using the 'any' data type since it negates the whole point of using Typescript. However, I am unable to change the data types. For example,

when I run a GraphQL query, I use this:

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

The data.loginEmail.accessToken is a string so I changed :any to string but I get errors that:

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

If I change the type to object , I get Property 'data' does not exist on type '{}'. TS2339 Property 'data' does not exist on type '{}'. TS2339 but the documentation also says that the mutation returns an object. So if not object or string, how else could I specify the data type for such an object? Is it even possible?

Similarly, when I map items like this after a query:

{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>
          ))}

How else could I specify c and I? There's no simple integer option for i.

Edit:

Schema:

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

GraphQL Code:

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

If you're using TypeScript, you should generate the types for both the data returned by the hook and the variables you pass to it. Type generation can be done using either the Apollo CLI or GraphQL Code Generator .

Once you've got your types, you can then use them with your hooks as shown here in the docs . By doing this, you will avoid having to explicitly assign types when consuming the data property returned by the hook. You will also add type safety for any variables passed to the hook.

Example usage from the docs:

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 } }
  );
  ...
}

Looks like your data structure corresponds to the following type interface:

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

Then on your data:

.then(({ data }: ExecutionResult<{data:MyDataReponse;}>) => {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM