'PropsWithChildren<WithUrqlProps>' 类型中缺少属性 'token',但类型 '{ token: string; }'

问题描述

我在导出认值 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);

解决方法

我有一个快速的方法可以解决您的类型问题

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

通过将 changePassword 类型转换为任何类型,它在编译时获得类型并且不显示任何升温

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

,

我可以用不同的方式打字,我希望这是正确的方式。我的方法是:

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

类型:

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

您可以从 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);