简体   繁体   English

React Typescript - 类型参数不可分配给“SetStateAction”类型的参数<user | record<string, never> >'</user>

[英]React Typescript - Argument of type is not assignable to parameter of type 'SetStateAction<User | Record<string, never>>'

I have a simple React web app with data (List of object) of Users, Todos And Posts, where I show, update and delete the data.我有一个简单的 React web 应用程序,其中包含用户、待办事项和帖子的数据(对象列表),我在其中显示、更新和删除数据。

I have a Component named UserView where I get the user data from the props, and then I save the data in the state with useEffect我有一个名为 UserView 的组件,我从道具中获取用户数据,然后使用 useEffect 将数据保存在 state 中

interface UserViewProps {
  userData: User;
}

export default function UserView({
  userData,
...
}: UserViewProps) {
  const [user, setUser] = useState<User | Record<string, never>>({});
  useEffect(() => {
...
    setUser({ ...userData });
  }, [todosData]);

The problem is when I want to change the user state from input to pass to a callback function with destructuring:问题是当我想通过解构将用户 state 从输入更改为传递给回调 function 时:

<input
        onChange={(e) =>
          setUser({
            ...user,
            name: e.target.value,
          })
        }

I receive the following TypeScript error:我收到以下 TypeScript 错误:

Argument of type '{ name: string; id: number; username: string; email: string; address: Address; phone: string; website: string; company: Company; } | { name: string; }' is not assignable to parameter of type 'SetStateAction<User | Record<string, never>>'.
Type '{ name: string; }' is not assignable to type 'SetStateAction<User | Record<string, never>>'.
Type '{ name: string; }' is not assignable to type 'Record<string, never>'.
Property 'name' is incompatible with index signature.
Type 'string' is not assignable to type 'never'.ts(2345)

When I change当我改变

 const [user, setUser] = useState<User | Record<string, never>>({});

to

  const [user, setUser] = useState<User | any>({});

Everything works How can I fix this TypeScript error?一切正常 我该如何解决这个 TypeScript 错误?

Full code below:完整代码如下:

import React, { useEffect, useState } from 'react';
import { Post, Todo, User } from '../../../helpers/utils';
import { StyledUserView } from './style';

interface UserViewProps {
  userData: User;
  todosData: Todo[];
  postsData: Post[];
  handleUserDelete: (userId: number) => void;
  handleUserUpdate: (updatedUser: User) => void;
}

export default function UserView({
  userData,
  todosData,
  postsData,
  handleUserDelete,
  handleUserUpdate,
}: UserViewProps) {
  const [isUncompletedTodo, setIsUncompletedTodo] = useState(false);
  const [isShowOtherData, setIsShowOtherData] = useState(false);
  const [user, setUser] = useState<User | any>({});
  useEffect(() => {
    if (todosData.find((todo) => todo.completed === false)) {
      setIsUncompletedTodo(true);
    } else {
      setIsUncompletedTodo(false);
    }
    setUser({ ...userData });
  }, [todosData]);
  return (
    <StyledUserView isUncompletedTodo={isUncompletedTodo}>
      ID: {user.id} <br />
      <label htmlFor={`${user.id}-name-input`}>Name:</label>{' '}
      <input
        onChange={(e) =>
          setUser({
            ...user,
            name: e.target.value,
          })
        }
        id={`${user.id}-name-input`}
        type="text"
        value={user.name}
      />{' '}
      <br />
      <label htmlFor={`${user.id}-email-input`}>Email:</label>{' '}
      <input
        onChange={(e) =>
          setUser({
            ...user,
            email: e.target.value,
          })
        }
        id={`${user.id}-email-input`}
        type="text"
        value={user.email}
      />{' '}
      <br />
      {isShowOtherData && (
        <section className="other-data">
          <label htmlFor={`${user.id}-street-input`}>Street:</label>{' '}
          <input
            onChange={(e) =>
              setUser({
                ...user,
                address: {
                  ...user.address,
                  street: e.target.value,
                },
              })
            }
            id={`${user.id}-street-input`}
            type="text"
            value={user.address.street}
          />{' '}
          <br />
          <label htmlFor={`${user.id}-city-input`}>City:</label>{' '}
          <input
            id={`${user.id}-city-input`}
            type="text"
            value={user.address.city}
            onChange={(e) =>
              setUser({
                ...user,
                address: {
                  ...user.address,
                  city: e.target.value,
                },
              })
            }
          />{' '}
          <br />
          <label htmlFor={`${user.id}-zip-code-input`}>Zip Code:</label>{' '}
          <input
            id={`${user.id}-zip-code-input`}
            type="text"
            value={user.address.zipcode}
            onChange={(e) =>
              setUser({
                ...user,
                address: {
                  ...user.address,
                  zipcode: e.target.value,
                },
              })
            }
          />{' '}
          <br />
        </section>
      )}
      <button
        onClick={() => {
          setIsShowOtherData(!isShowOtherData);
        }}
      >
        {isShowOtherData ? 'Hide Other Data' : 'Show Other Data'}
      </button>
      <button onClick={() => handleUserUpdate(user)}>Update</button>
      <button
        onClick={() => {
          handleUserDelete(user.id);
        }}
      >
        Delete
      </button>
    </StyledUserView>
  );
}

You can try to change你可以尝试改变

const [user, setUser] = useState<User | Record<string, never>>({});

// to 
const [user, setUser] = useState<User | Record<string, any>>({});

//or 
const [user, setUser] = useState<User | Record<string, string>>({});

Add inital user name as empty string将初始用户名添加为空字符串

  const [user, setUser] = useState<{ name: string }>({
    name: ""
  });

code sanbox 代码沙箱

if the name is a variable then you need to do [name] else it is static then "name"如果名称是一个变量,那么你需要做 [名称] 否则它是 static 然后是“名称”

 <input
 onChange={(e) =>
  setUser(prv=>{
   ...prv,
    [name]: e.target.value,
   })
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript/React-Native:'string | 类型的参数 null' 不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - Typescript/React-Native: Argument of type 'string | null' is not assignable to parameter of type 'SetStateAction<never[]>' 类型参数不可分配给“SetStateAction”类型的参数<never[]> &#39;。 在反应中 - Argument of type is not assignable to parameter of type 'SetStateAction<never[]>'. in React &#39;x&#39;类型的React Typescript参数不可分配给&#39;SetStateAction&#39;类型的参数<x]> &#39; - React Typescript Argument of type 'x' is not assignable to parameter of type 'SetStateAction<x]>' Typescript 抱怨 React useState setter `Argument of type 'Dispatch <setstateaction<never[]> &gt;' 不可分配给参数</setstateaction<never[]> - Typescript complaining about React useState setter `Argument of type 'Dispatch<SetStateAction<never[]>>' is not assignable to parameter of React js Typescript “字符串”类型的参数不可分配给“SetStateAction”类型的参数<number> '</number> - React js Typescript Argument of type 'string' is not assignable to parameter of type 'SetStateAction<number>' Typescript 索引签名错误:类型错误:类型参数不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - Typescript index signature error : Type error: Argument of type is not assignable to parameter of type 'SetStateAction<never[]>' React TypeScript:参数不可分配给“从不”类型的参数 - React TypeScript: Argument is not assignable to parameter of type 'never' ReactJS:“(bullets:never[])=&gt; string[]”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - ReactJS: Argument of type '(bullets: never[]) => string[]' is not assignable to parameter of type 'SetStateAction<never[]>' “未知 []”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - Argument of type 'unknown[]' is not assignable to parameter of type 'SetStateAction<never[]>' “void”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '.ts(2345)</never[]> - Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.ts(2345)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM