为了账号安全,请及时绑定邮箱和手机立即绑定

在 Typescript 中从数组中随机选取 N 个项目的函数

在 Typescript 中从数组中随机选取 N 个项目的函数

慕码人2483693 2023-07-06 17:48:08
我使用泛型类型参数:T extends unknown[],因为此函数应该适用于任何类型的数组。export const pickRandomItems = <T extends unknown[]> (arr: T, n: number): T => {  const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());  return shuffled.slice(0, n);};但我在声明中收到以下错误return:如果我进行类型断言,它就会消失。但为什么有必要呢?难道我做错了什么?笔记:下面的行被评估为unknown[],那么为什么类型断言仍然是必要的呢?const result = shuffled.slice(0, n);
查看完整描述

2 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

将类型参数更改为数组项,而不是整个数组:


export const pickRandomItems = <T extends unknown> (arr: T[], n: number): T[] => {

  const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());

  return shuffled.slice(0, n);

};


虽然T extends unknown[]does 意味着T可以是任何数组,但它也可以是 的子类型Array,这意味着slice不会返回适当的类型(它将返回Array而不是任何T类型)。通常,您不能将具体类型分配给泛型类型参数,因为泛型类型参数可以是调用者决定的任何子类型,而您在实现中使用特定的具体类型。


查看完整回答
反对 回复 2023-07-06
?
繁花不似锦

TA贡献1851条经验 获得超4个赞

您遇到的问题是 T 可以是 的任何子类型unknown[],但是您的函数返回一个数组。因此,打字稿警告您数组不能转换为T,这可能是数组的某个子类。相反,您可以将 T 更改为项目,并采用可迭代作为参数并返回一个数组:


// trailing comma in generic so ts doesn't confuse with jsx

export const pickRandomItems = <T,> (arr: Iterable<T>, n: number): T[] => {

  const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());

  return shuffled.slice(0, n);

};


查看完整回答
反对 回复 2023-07-06
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信