TestDrive:
现在我像这样应用上面的函数:
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
类型,这就是{}
或{ {1}}无效。
ab.a
如何定义同时包含'a'和'b'属性的ab类型?
答案 0 :(得分:1)
您需要明确告诉打字稿reduce
的返回类型是什么,打字稿将无法推断出该类型。
返回类型应该是所有函数返回类型的交集。我们可以使用类型查询(AT[number]
)获得函数类型的并集,并可以使用ReturnType
条件类型获取返回类型。要将返回类型的并集转换为交集,我们可以使用here中的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 }