【问题标题】:Property 'token' is missing in type 'PropsWithChildren<WithUrqlProps>' but required in type '{ token: string; }'类型“PropsWithChildren<WithUrqlProps>”中缺少属性“token”,但类型“{ token: string; }'
【发布时间】:2021-03-17 17:49:34
【问题描述】:

我在导出默认值 withUrqlClient(createUrqlClient)(ChangePassword) 的 (ChangePassword) 处收到此错误:

'FunctionComponent & { getInitialProps?(context: NextPageContext): { token: string; } |承诺; }' 不可分配给类型为“NextComponentType”的参数。 输入 'FunctionComponent & { getInitialProps?(context: NextPageContext): { token: string; } |承诺; }' 不可分配给类型 'FunctionComponent & { getInitialProps?(context: PartialNextContext): {} |承诺; }'。 输入 'FunctionComponent & { getInitialProps?(context: NextPageContext): { token: string; } |承诺; }' 不可分配给类型 'FunctionComponent'。 参数 'props' 和 'props' 的类型不兼容。 类型 'PropsWithChildren' 不可分配给类型 'PropsWithChildren'。 “PropsWithChildren”类型中缺少属性“token”,但类型“{ token: string; }'.ts(2345)

代码如下:

import { NextPage } from "next";
import { Wrapper } from "../../components/Wrapper";
import { Formik, Form } from "formik";
import { toErrorMap } from "../../utils/toErrorMap";
import { InputField } from "../../components/InputField";
import { Box, Button, Link, Flex } from "@chakra-ui/react";
import { useChangePasswordMutation } from "../../generated/graphql";
import { useRouter } from "next/router";
import { withUrqlClient } from "next-urql";
import { createUrqlClient } from "../../utils/createUrqlClient";
import NextLink from "next/link";

const ChangePassword: NextPage<{ token: string }> = ({ token }) => {
  const router = useRouter();
  const [, changePassword] = useChangePasswordMutation();
  const [tokenError, setTokenError] = useState("");
  return (
    <Wrapper variant="small">
      <Formik
        initialValues={{ newPassword: "" }}
        onSubmit={async (values, { setErrors }) => {
          const response = await changePassword({
            newPassword: values.newPassword,
            token,
          });
          if (response.data?.changePassword.errors) {
            const errorMap = toErrorMap(response.data.changePassword.errors);
            if ("token" in errorMap) {
              setTokenError(errorMap.token);
            }
            setErrors(errorMap);
          } else if (response.data?.changePassword.user) {
            // worked
            router.push("/");
          }
        }}
      >
        {({ isSubmitting }) => (
          <Form>
            <InputField
              name="newPassword"
              placeholder="new password"
              label="New Password"
              type="password"
            />
            {tokenError ? (
              <Flex>
                <Box mr={2} style={{ color: "red" }}>
                  {tokenError}
                </Box>
                <NextLink href="/forgot-password">
                  <Link>click here to get a new password</Link>
                </NextLink>
              </Flex>
            ) : null}
            <Button
              mt={4}
              type="submit"
              isLoading={isSubmitting}
              variantColor="teal"
            >
              change password
            </Button>
          </Form>
        )}
      </Formik>
    </Wrapper>
  );
};

ChangePassword.getInitialProps = ({ query }) => {
  return {
    token: query.token as string,
  };
};

export default withUrqlClient(createUrqlClient)(ChangePassword);

【问题讨论】:

    标签: reactjs typescript next.js change-password urql


    【解决方案1】:

    我有一个快速解决你的类型问题的方法

    export default withUrqlClient(createUrqlClient)(ChangePassword as any);
    

    通过将 changePassword 类型转换为任何它在编译时获得的类型并且它不会显示任何变暖

    (注意:如果您按照此操作,将不会自动完成或键入)

    【讨论】:

      【解决方案2】:

      我可以用不同的方式输入我的,我希望这是正确的方式。我的做法是:

      export default withUrqlClient(createUrlClient)(
        ChangePassword as FunctionComponent<
          PropsWithChildren<WithUrqlProps | { token: string }>
        >
      );
      

      类型:

      • FunctionComponentPropsWithChildren 是从“react”导入的
      • WithUrqlProps 是从“next-urql”导入的

      【讨论】:

        【解决方案3】:

        您可以从useRouter 而不是getInitialProps 获取查询令牌。

        import { Box, Button, Flex, Link } from "@chakra-ui/react";
        import { Form, Formik } from "formik";
        import { withUrqlClient } from "next-urql";
        import { useRouter } from "next/router";
        import React, { useState } from "react";
        import InputField from "../../components/InputField";
        import Wrapper from "../../components/Wrapper";
        import { useChangePasswordMutation } from "../../generated/graphql";
        import { createUrqlClient } from "../../utils/createUrqlClient";
        import { toErrorMap } from "../../utils/toErrorMap";
        import NextLink from "next/link";
        
        const ChangePassword = () => {
          const [, changePassword] = useChangePasswordMutation();
          const [tokenError, setTokenError] = useState("");
        
          const router = useRouter();
          const { token } = router.query;
        
          return (
            <Wrapper variant="small">
              <Formik
                initialValues={{ newPassword: "" }}
                onSubmit={async (values, { setErrors }) => {
                  const response = await changePassword({
                    newPassword: values.newPassword,
                    token: token as string,
                  });
                  if (response.data?.changePassword.errors) {
                    const errorMap = toErrorMap(response.data.changePassword.errors);
                    if ("token" in errorMap) {
                      setTokenError(errorMap.token);
                    }
                    setErrors(errorMap);
                  } else if (response.data?.changePassword.user) {
                    router.push("/");
                  }
                }}
              >
                {({ isSubmitting }) => (
                  <Form>
                    <InputField
                      name="newPassword"
                      placeholder="new password"
                      label="New Password"
                      type="password"
                    />
                    {tokenError ? (
                      <Flex>
                        <Box mr={2} color="red">
                          {tokenError}
                        </Box>
                        <NextLink href="/forgot-password">
                          <Link>click here to get a new one</Link>
                        </NextLink>
                      </Flex>
                    ) : null}
                    <Box mt={4}>
                      <Button type="submit" isLoading={isSubmitting} colorScheme="teal">
                        change password
                      </Button>
                    </Box>
                  </Form>
                )}
              </Formik>
            </Wrapper>
          );
        };
        
        export default withUrqlClient(createUrqlClient)(ChangePassword);
        
        

        【讨论】:

          猜你喜欢
          • 2018-03-03
          • 1970-01-01
          • 2019-10-21
          • 2021-07-15
          • 2020-05-18
          • 2022-01-19
          • 2021-07-26
          • 1970-01-01
          • 2018-10-25
          相关资源
          最近更新 更多