typescript - 如果数组的每个元素都是一个函数,如何合并数组中的元素?
问题描述
export type MakeActionType = (name: string) => {[key: string]: string}
const combineActionType = <AT extends (MakeActionType | undefined)[]>(...actionTypeList: AT) => (name: string) => {
return actionTypeList.reduce(
(previous, makeActionType) => {
const actionType = makeActionType ? makeActionType(name) : {}
return {
...previous,
...actionType,
}
},
{}
)
}
现在我像这样应用上面的函数:
const abAction = combineActionType((name) => ({a: 'a'}), (name) => ({b: 'b'}))
const ab = abAction('ab')
我想ab
包含a
和b
属性,但ab
返回{}
类型,这就是为什么ab.a
或ab.b
不工作。
ab.a //err
ab.b //err
如何定义包含“a”和“b”属性的 ab 类型?
解决方案
您需要明确告诉 typescript 的返回类型是什么reduce
,typescript 将无法推断类型。
返回类型应该是所有函数返回类型的交集。我们可以使用类型查询 () 获取函数类型的联合,并且可以使用条件类型AT[number]
获取返回类型。ReturnType
要将返回类型的并集转换为交集,我们可以使用此处UnionToIntersection
的类型(不要忘记支持 jcalz)
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
export type MakeActionType = (name: string) => { [key: string]: string }
const combineActionType = <AT extends (MakeActionType | undefined)[]>(...actionTypeList: AT) => (name: string) => {
return actionTypeList.reduce(
(previous, makeActionType) => {
const actionType = makeActionType ? makeActionType(name) : {}
return {
...previous,
...actionType,
}
},
{}
) as UnionToIntersection<ReturnType<Exclude<AT[number], undefined>>>
}
const abAction = combineActionType((name) => ({a: 'a'}), (name) => ({b: 'b'}))
const ab = abAction ('a') // { a: string } & { b: string }
推荐阅读
- reactjs - 通过酶测试文档打印 - React
- python - 相同向量之间的余弦距离不等于 0
- java - 当需要保留两个文件的更改时,如何使用 TortoiseSVN 使主干和分支中的两个文件相同?
- lua - 在 Lua 循环中更改步骤
- scala - Spark 驱动程序进程中的默认未捕获异常处理程序
- c# - 如何形成TaskCompletionSource的集合
并保持类型安全 - json - JMeter:如何获取 JSON 路径中的坐标
- mysql - MYSQL 选择限制每个唯一值的最后 5 个结果
- r - 替换列中的单词
- java - 如果系统空闲 5 分钟,如何将页面重定向到“/login”页面?