我收到打字稿错误,
错误 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的函数,唯一安全的东西是既X
又Y
的东西,或者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 个数组,而不是另一个数组。也许上面的更改可以解决这个问题。请确认。