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

我使用泛型类型参数: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:

http://img2.sycdn.imooc.com/64a68df60001ebd306470076.jpg

http://img1.sycdn.imooc.com/64a68dfd0001805a06440089.jpg

如果我进行类型断言,它就会消失。但为什么有必要呢?难道我做错了什么?

http://img1.sycdn.imooc.com/64a68e0900014b2c06470078.jpg

笔记:

下面的行被评估为unknown[],那么为什么类型断言仍然是必要的呢?

const result = shuffled.slice(0, n);


慕码人2483693
浏览 270回答 2
2回答

ibeautiful

将类型参数更改为数组项,而不是整个数组: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类型)。通常,您不能将具体类型分配给泛型类型参数,因为泛型类型参数可以是调用者决定的任何子类型,而您在实现中使用特定的具体类型。

繁花不似锦

您遇到的问题是 T 可以是 的任何子类型unknown[],但是您的函数返回一个数组。因此,打字稿警告您数组不能转换为T,这可能是数组的某个子类。相反,您可以将 T 更改为项目,并采用可迭代作为参数并返回一个数组:// trailing comma in generic so ts doesn't confuse with jsxexport const pickRandomItems = <T,> (arr: Iterable<T>, n: number): T[] => {&nbsp; const shuffled = Array.from(arr).sort(() => 0.5 - Math.random());&nbsp; return shuffled.slice(0, n);};
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript