首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型'(prev: Phone[]) => Phone[]‘的参数不能分配给'Phone[]’类型的参数

类型'(prev: Phone[]) => Phone[]‘的参数不能分配给'Phone[]’类型的参数
EN

Stack Overflow用户
提问于 2022-08-27 21:02:35
回答 2查看 52关注 0票数 1

因此,我使用useState和回调作为参数:setLikedGadgets((prev: Phone[]) => [...prev, info]);

但我收到了错误:

Argument of type '(prev: Phone[]) => Phone[]' is not assignable to parameter of type 'Phone[]'. Type '(prev: Phone[]) => Phone[]' is missing the following properties from type 'Phone[]': pop, push, concat, join, and 28 more.

另一方面,如果我使用的是prev代码,而不是setLikedGadgets([...likedGadgets, info]);代码,那么这一切都能工作。但是如何使它以正常的方式在打字稿中工作呢?

代码语言:javascript
复制
import { useContext } from 'react';
import { likedContext } from '../context/LikedContext';
import { Phone } from '../types/Phone';

export const useLikes = () => {
  const {
    likedGadgets
    arrayOfLiked,
    setLikedGadgets,
    setArrayOfLiked,
  }
    = useContext(likedContext);

  const addToLiked = (info: Phone) => {
    if (arrayOfLiked.includes(info.id)) {
      return;
    }

    if (arrayOfLiked.length === 0) {
      setLikedGadgets([info]);
      setArrayOfLiked([info.id]);
    } else {
      setLikedGadgets((prev: Phone[]) => [...prev, info]);
    }
  };

  return { addToLiked };
};

顺便说一句,setLikedGadgets的类型是(value: Phone[]) => void

这是我无法更改的,因为这是我在createContext()初始化期间定义它的方式。

代码语言:javascript
复制
type LikedContextInterface = {
  likedGadgets: Phone[];
  setLikedGadgets: (value: Phone[]) => void;
  arrayOfLiked: string[];
  setArrayOfLiked: (value: string[]) => void;
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-28 00:57:43

代码语言:javascript
复制
type LikedContextInterface = {
  likedGadgets: Phone[];
  setLikedGadgets: (value: Phone[]) => void;
  arrayOfLiked: string[];
  setArrayOfLiked: (value: string[]) => void;
};

在这个定义中,setLikedGadgets是一个接收一系列电话的函数。将函数传递给setLikedGadgets违反了类型,所以类型记录显示了一个错误。

根据您使用它的方式,setLikedGadgets似乎是一个react函数。这意味着它可以接受新值,也可以接受从旧状态计算新状态的函数。如果您希望保留该行为,则需要将该信息包含在该类型中。

如果您想从react导入类型,它们是:

代码语言:javascript
复制
import { Dispatch, SetStateAction } from 'react';

type LikedContextInterface = {
  likedGadgets: Phone[];
  setLikedGadgets: Dispatch<SetStateAction<Phone[]>>;
  arrayOfLiked: string[];
  setArrayOfLiked: (value: string[]) => void; // <--- this may want similar treatment
};

或者,如果你想自己写,你可以:

代码语言:javascript
复制
setLikedGadgets: (value: Phone[] | ((prev: Phone[]) => Phone[])) => void;
票数 2
EN

Stack Overflow用户

发布于 2022-08-28 10:26:41

感谢尼古拉斯塔,这里是解决问题的办法,总结起来。

因此,bug是在createContext初始化中,更具体的类型是对初始值进行防御。这里已经有固定的代码了。

代码语言:javascript
复制
import { createContext, useState } from 'react';
import { Phone } from '../types/Phone';

type LikedContextInterface = {
  likedGadgets: Phone[];
  setLikedGadgets: (value: Phone[] | ((prev: Phone[]) => Phone[])) => void;
  likedGadgetsID: string[];
  setLikedGadgetsID: (value: string[] | ((prev: string[]) => string[])) => void;
};

export const likedContext = createContext<LikedContextInterface>({
  likedGadgets: [],
  setLikedGadgets: () => {},
  likedGadgetsID: [],
  setLikedGadgetsID: () => {},
});

type Props = {
  children: React.ReactNode;
};

export const LikedContextProvider: React.FC<Props> = ({ children }) => {
  const [likedGadgets, setLikedGadgets] = useState<Phone[]>([]);
  const [likedGadgetsID, setLikedGadgetsID] = useState<string[]>([]);

  return (
    <likedContext.Provider value={
      {
        likedGadgets, setLikedGadgets, likedGadgetsID, setLikedGadgetsID,
      }
    }
    >
      { children }
    </likedContext.Provider>
  );
};

LikedContextInterface类型中,我错误地设置了状态设置函数的类型setLikedGadgetssetArrayOfLiked

在此之前

代码语言:javascript
复制
setLikedGadgets: (value: Phone[]) => void;

这意味着它只允许接收Phone[]类型的参数。

之后

代码语言:javascript
复制
setLikedGadgets: (value: Phone[] | ((prev: Phone[]) => Phone[])) => void;

现在它可以接收带有Phone[]类型参数的((prev: Phone[]) => Phone[]))回调或Phone[]回调,并返回Phone[]。

另外,Dispatch<SetStateAction<Phone[]>>不是为我工作的,因为类型防御是外部功能组件。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73514406

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档