javascript - 如何在打字稿中编写一个泛型函数,其中两个参数的参数为 value 或 value []
问题描述
我正在尝试创建一个通用函数,它将接受一个字符串 hasMapName 和另一个参数键作为字符串 | string[] 和一个将返回 T | 的回调 T[]。
如果键是字符串,回调应该返回 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);
}
但是我在 getDataForKey 中的键处遇到 tserror。
错误:
Argument of type 'K extends string[] ? string[] : string' is not assignable to parameter of type 'string'.
Type 'string | string[]' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.
Type 'string | string[]' is not assignable to type 'string'.
Type 'string[]' is not assignable to type 'string'.
更新1:
请找到 getDataForKeys 和 getDataForKey 函数的声明。
declare function getDataForKey<T>(
hashMapName: string,
key: string,
serviceCallBack: () => Promise<T>
)
declare function getDataForKeys<T>(
hashMapName: string,
key: string[],
serviceCallBack: () => Promise<T[]>
)
由于我们严格遵守 noExplicitAny 政策,我们将无法对功能参数使用任何关键字。
尝试@Dmitriy 答案后,现在面临以下问题。
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[]'
解决方案
对于这个用例,您应该使用重载函数而不是条件类型:
declare function getDataForKey<T>(...args: any[]): Promise<T>;
declare function getDataForKeys<T>(...args: any[]): Promise<T[]>;
export function getData<T>(
hashMapName: string,
keys: string,
serviceCallBack: () => Promise<T>
): Promise<T>
export function getData<T>(
hashMapName: string,
keys: string[],
serviceCallBack: () => Promise<T[]>
): Promise<T[]>
export function getData<T>(
hashMapName: string,
keys: string | string[],
serviceCallBack: (() => Promise<T[]>) | (() => Promise<T>)
): Promise<T> | Promise<T[]> {
return Array.isArray(keys)
? getDataForKeys<T>(hashMapName, keys, serviceCallBack)
: getDataForKey<T>(hashMapName, keys, serviceCallBack);
}
getData("foo", "fooo", async () => "bar"); // works
getData("foo", ["fooo"], async () => ["bar"]); // works
getData("foo", ["fooo"], async () => "bar"); // error
// also works because T is not constrained to be non-array
getData("foo", "fooo", async () => ["bar"]);
推荐阅读
- android - Kotlin(Android)中的倒数计时器类中的问题
- angular - Angular Subscription 不调用 Next
- r - r - 基于另一列上不同值的总和
- python - 我应该如何在 python 3.8 中使用 SharedMemory 清理内存?Close() 和 unlink() 方法不起作用
- azure - 未在 module.vm 中声明托管资源“azurerm_network_interface”“myterraformnic”。天蓝色
- arrays - 将包含数组的字符串转换为 json 对象
- c++ - 序列化后重构一个 QSqlQuery
- python - Spyder 绘图不允许足够的用户控制
- python - Django - TypeError: must be real number, not F (annotate)
- r - 如何从r中的多个url下载json数据