8

我正在尝试创建一个函数,它接受数字数组或字符串数​​组并从该数组返回 Set,如下所示:

const f = (arr: number[] | string[]): number[] | string[] => {
    return [...new Set(arr)]; 
}

并得到一个错误:

没有重载匹配此调用。
重载 1 of 2,'(iterable?: Iterable | null | undefined): Set',给出了以下错误。'number[] 类型的参数 | string[]' 不可分配给“Iterable |”类型的参数 空 | 不明确的'。类型 'string[]' 不可分配给类型 'Iterable'。'Symbol.iterator.next(...)' 返回的类型在这些类型之间不兼容。类型 'IteratorResult<string, any>' 不可分配给类型 'IteratorResult<number, any>'。类型“IteratorYieldResult”不可分配给类型“IteratorResult<number, any>”。类型“IteratorYieldResult”不可分配给类型“IteratorYieldResult”。类型“字符串”不可分配给类型“数字”。
重载 2 of 2,'(values?: readonly number[] | null | undefined): Set',给出了以下错误。'number[] 类型的参数 | string[]' 不可分配给'readonly number[] 类型的参数 | 空 | 不明确的'。类型 'string[]' 不能分配给类型 'readonly number[]'。类型“字符串”不可分配给类型“数字”。

我可以将传入类型从更改为number[] | string[](number | string)[]但这意味着数组中可能同时是数字和字符串,这不是我想要的。

const f = (arr: (number | string)[]): (number | string)[] => {
    return [...new Set(arr)];
}

f([1,2,3]);        // ok
f(['1','2','3']);  // ok
f([1,2,'3','4']);  // ok, but should be err
f([true, {}, 1]);  // err, like it should be
4

3 回答 3

4

编辑:似乎这与某些 TS 配置有关。一种方法是传播要从中创建集合的数组并转换返回值,如下所示:

const f = (arr: number[] | string[]): number[] | string[] => {
    return Array.from(new Set([...arr])) as number[] | string[];
}

正如 udalmik 所说,您可以使用any虽然这有点失败。

于 2021-11-09T23:43:21.050 回答
1

我认为这两种方法都可能效果更好

const f = <T extends number[] | string[]>(arr: T):  T => {
    return <T> [...new Set(arr as any[])];
}

let f1 = f([1,2,3,4,5,5,5]);
let f2 = f(['a','b','c','c','c']);
let f3 = f(['a','b','c','a','b',1,2,3,4]);//error
function f(arr:number[]):number[];
function f(arr:string[]):string[];
function f(arr:any[]):any[]{
    return [...new Set(arr)];
}

let f1 = f([1,2,3,4,5,5,5]);
let f2 = f(['a','b','c','c','c']);
let f3 = f(['a','b','c','a','b',1,2,3,4]);//error

这样,该函数只接受数字或字符串数​​组,但不能同时接受两者,并且它保留了返回类型信息。如果你传入一个数字数组,那么打字稿就知道返回值是一个数字数组。

于 2021-12-05T08:25:49.297 回答
1

您可以通过将参数转换为any[]

function f(arg: number[] | string[]): number[] | string[] {
    return [...new Set(arg as any[])];
}
于 2021-11-09T23:56:34.613 回答