繁体   English   中英

所有返回类型与函数列表的交集类型

[英]Type for intersection of all return types with list of functions

假设我有一个像这样的函数数组:

const foo: Array< () => object > = [
    () => ({ one: 'fish' }),
    () => ({ two: 'fish' }),
    () => ({ red: 'fish' }),
    () => ({ blue: 'fish' })        
]

是否可以编写一种类型来交叉所有这些函数的返回类型?

{
  one: string,
  two: string,
  red: string,
  blue: string,
}

基本上,如果您将所有这些函数减少到一个结果中会产生什么结果的类型。

有趣的问题。 这可以使用映射类型和条件类型的组合来完成; 我们需要:

  • 去掉类型注解Array<() => object>这样数组的实际内容就可以用来构造类型了,
  • 从数组类型中获取函数类型,
  • 获取这些函数类型的返回类型,
  • 这给出了一个像{one: string} | {two: string} | {red: string} | {blue: string}这样的联合{one: string} | {two: string} | {red: string} | {blue: string} {one: string} | {two: string} | {red: string} | {blue: string} {one: string} | {two: string} | {red: string} | {blue: string}所以我们需要能够获取属性名称( keyof不适用于这样的联合),
  • 获取与联合中给定属性名称关联的值类型,
  • 最后,将结果构造为从这些属性名称到这些值类型的映射。

这是一个实现:

const foo = [
    () => ({ one: 'fish' }),
    () => ({ two: 'fish' }),
    () => ({ red: 'fish' }),
    () => ({ blue: 'fish' })
];

type ComponentType<A extends any[]> = A extends (infer U)[] ? U : never

type ReturnsUnion = ReturnType<ComponentType<typeof foo>>
// {one: string} | {two: string} | {red: string} | {blue: string}

type KeyOfUnion<T> = T extends infer U ? keyof U : never
// KeyOfUnion<ReturnsUnion> = 'one' | 'two' | 'red' | 'blue'

type ValueInUnion<T, K extends PropertyKey> = T extends { [k in K]: infer V } ? V : never

type Result = { [K in KeyOfUnion<ReturnsUnion>]: ValueInUnion<ReturnsUnion, K> }
// { one: string, two: string, red: string, blue: string }

游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM