类型为"number"的参数不能分配给array.include()中类型为"never"的参数



我收到打字稿错误,

错误 TS2345:类型为"数字"的参数不可分配给参数 类型为"字符串和数字"。类型"数字"不可分配给类型 "字符串"。112

setProductPrices(productPrices.filter(
(p): boolean => !selectedProductIds.includes(p.id)));
^^^^

从以下代码:

export interface IProductPrice {
id: number;
}
const [productPrices, setProductPrices] = useState<IProductPrice[]>([]);
const [selectedProductIds, setSelectedProductIds] = useState<string[] | number[]>([]);
const deleteSelectedProducts = (): void => {
setProductPrices(productPrices.filter((p): boolean => !selectedProductIds.includes(p.id)));
setSelectedProductIds([]);
};

includes()方法据说是 期望参数为"从不",而p.id是一个数字。有谁知道如何解决这个问题?

问题

当您具有不同类型的数组的联合时,无法对它们调用方法。

原因

你有string[] | number[],所以.filter是:

((filterFunc: (x: string) => boolean) => string[]) 
| ((filterFunc: (x: number) => boolean) => number[])

当 TS 组合这些签名时,它将把两个filterFunc签名合并在一起:

((x: number) => boolean) 
| ((x: string) => boolean)

这有点不直观,但这简化了(x: number & string) => boolean. 因为如果你有一个接受X的函数,或者一个接受Y的函数,唯一安全的东西是既XY的东西,或者X & Y

然而,number & string是一种不可能的类型,它"简化"为never. 因此,为什么签名是(x: never) => boolean.

修复

理想情况下,您只能使用string[]number[],但不能同时使用两者。 (光看代码,就有点神秘了,为什么id只能是数字,而"选定的产品ID"也可以是字符串(


但是,如果您确实需要同时支持字符串和数字,最简单的解决方法是使用Array<string | number>而不是string[] | number[]:单个数组类型没有尝试将两个.filter签名联合在一起的问题。

您可以将状态更改为该类型:

const [selectedProductIds, setSelectedProductIds] = useState<Array<string | number>>([]);

这很简单,但缺点是它将允许混合字符串和数字的数组,这可能是不可取的。 (例如setSelectProductIds(['0', 1, '2'])


如果没有,您可以暂时投射到Array<string | number>,执行过滤器,然后投射回string[] | number[]。 这不是超级干净,但应该是安全的:

setProductPrices(
(productPrices as Array<string | number>).filter((p): boolean => !selectedProductIds.includes(p.id)) as (string[] | number[])
);

供您使用状态而不是

const [selectedProductIds, setSelectedProductIds] = useState<string[] | number[]>([]);

你能试试吗

const [selectedProductIds, setSelectedProductIds] = useState< (string|number)[]>([]);

相反?

这是因为可能缺少一些代码,您将selectedProductIds设置为字符串数组。在您的代码中,您严格将其定义为 1 个数组,而不是另一个数组。也许上面的更改可以解决这个问题。请确认。

相关内容

  • 没有找到相关文章

最新更新