Javascript 如何在typescript中为两个参数编写参数为value或value[]的泛型函数

Javascript 如何在typescript中为两个参数编写参数为value或value[]的泛型函数,javascript,typescript,generics,ecmascript-6,Javascript,Typescript,Generics,Ecmascript 6,我正在尝试创建一个泛型函数,它将接受一个sting hasmappname和另一个参数键string | string[],以及一个返回T | T[]的回调 如果键是string,则回调应返回T,如果键是string[],则应返回T[] 尝试了以下代码: export function getData<K extends string | string[], T>( hashMapName: string, keys: K extends strin

我正在尝试创建一个泛型函数,它将接受一个sting hasmappname和另一个参数键string | string[],以及一个返回T | T[]的回调

如果键是string,则回调应返回T,如果键是string[],则应返回T[]

尝试了以下代码:


    export function getData<K extends string | string[], T>(
      hashMapName: string,
      keys: K extends string[] ? string[] : string,
      serviceCallBack: K extends string[] ? () => Promise<T[]> : () => Promise<T>
    ): Promise<T> {
      return Array.isArray(keys)
        ? getDataForKeys<T>(hashMapName, keys, serviceCallBack)
        : getDataForKey<T>(hashMapName, keys, serviceCallBack);
    }

更新1:

请查找getDataForKey和getDataForKey函数的声明


    declare function getDataForKey<T>(
      hashMapName: string,
      key: string,
      serviceCallBack: () => Promise<T>
    )

    declare function getDataForKeys<T>(
      hashMapName: string,
      key: string[],
      serviceCallBack: () => Promise<T[]>
    )


声明函数getDataForKey(
hashMapName:string,
键:字符串,
serviceCallBack:()=>承诺
)
声明函数getDataForKeys(
hashMapName:string,
关键字:字符串[],
serviceCallBack:()=>承诺
)
由于我们严格遵循noExplicitAny策略,因此我们将无法对函数参数使用任何关键字

在尝试了@dmitry答案之后,现在面临以下问题

Argument of type '(() => Promise<T[]>) | (() => Promise<T>)' is not assignable to parameter of type '() => Promise<T[]>'.
  Type '() => Promise<T>' is not assignable to type '() => Promise<T[]>'.
    Type 'Promise<T>' is not assignable to type 'Promise<T[]>'.
      Type 'T' is not assignable to type 'T[]'
“(()=>Promise)”类型的
参数不可分配给“()=>Promise”类型的参数。
类型“()=>Promise”不可分配给类型“()=>Promise”。
类型“Promise”不可分配给类型“Promise”。
类型“T”不可分配给类型“T[]”

对于此用例,您应该使用重载函数而不是条件类型:

声明函数getDataForKey(…args:any[]):Promise;
声明函数getDataForKeys(…args:any[]):Promise;
导出函数getData(
hashMapName:string,
键:字符串,
serviceCallBack:()=>承诺
):承诺
导出函数getData(
hashMapName:string,
关键字:字符串[],
serviceCallBack:()=>承诺
):承诺
导出函数getData(
hashMapName:string,
键:string | string[],
serviceCallBack:(()=>承诺)|(()=>承诺)
):允诺{
返回数组.isArray(键)
?getDataForKeys(hashMapName、键、serviceCallBack)
:getDataForKey(hashMapName、键、serviceCallBack);
}
getData(“foo”,“fooo”,async()=>“bar”);//作品
getData(“foo”、[“fooo”]、异步()=>[“bar”]);//作品
getData(“foo”、[“fooo”],异步()=>“bar”);//错误
//也可以工作,因为T不被约束为非数组
getData(“foo”,“fooo”,async()=>[“bar]”);

对于此用例,您应该使用重载函数而不是条件类型:

声明函数getDataForKey(…args:any[]):Promise;
声明函数getDataForKeys(…args:any[]):Promise;
导出函数getData(
hashMapName:string,
键:字符串,
serviceCallBack:()=>承诺
):承诺
导出函数getData(
hashMapName:string,
关键字:字符串[],
serviceCallBack:()=>承诺
):承诺
导出函数getData(
hashMapName:string,
键:string | string[],
serviceCallBack:(()=>承诺)|(()=>承诺)
):允诺{
返回数组.isArray(键)
?getDataForKeys(hashMapName、键、serviceCallBack)
:getDataForKey(hashMapName、键、serviceCallBack);
}
getData(“foo”,“fooo”,async()=>“bar”);//作品
getData(“foo”、[“fooo”]、异步()=>[“bar”]);//作品
getData(“foo”、[“fooo”],异步()=>“bar”);//错误
//也可以工作,因为T不被约束为非数组
getData(“foo”,“fooo”,async()=>[“bar]”);

感谢您的快速回复,我尝试了您的答案,但遇到了另一个问题,因为我们对函数参数遵循严格的不适用政策。用函数声明和我遇到的问题更新了问题。感谢您的快速回复,我尝试了您的答案,但遇到了一个不同的问题,因为我们对函数参数遵循严格的noExplicitAny策略。用函数声明和我遇到的问题更新了问题。
Argument of type '(() => Promise<T[]>) | (() => Promise<T>)' is not assignable to parameter of type '() => Promise<T[]>'.
  Type '() => Promise<T>' is not assignable to type '() => Promise<T[]>'.
    Type 'Promise<T>' is not assignable to type 'Promise<T[]>'.
      Type 'T' is not assignable to type 'T[]'