从类型联合定义打字稿函数签名[重复]

Posted

技术标签:

【中文标题】从类型联合定义打字稿函数签名[重复]【英文标题】:Define typescript function signature from union of types [duplicate] 【发布时间】:2021-01-07 08:45:14 【问题描述】:

我想从类型的联合中定义一个函数的类型:

type MyEvent =
|  type: 'hello', payload:  
|  type: 'start', payload:  date: Date  


type On<Event> = Event extends  type: infer EventType, payload: infer EventPayload 
  ? (type: EventType, callback: (payload: EventPayload) => void) => void
  : never

const on: On<MyEvent>
on('hello', (payload) => void)

但编译器将第一个参数的类型定义为“从不”

On 返回一个看起来不错的类型。我也尝试了返回的原始类型,结果相同:

type RawOn =
| ((type: "hello", callback: (payload: ) => void) => void)
| ((type: "start", callback: (payload:  date: Date ) => void) => void)

const raw_on: RawOn
raw_on('hello', (payload) => void)

如何定义“函数签名的联合类型”?

Playground

【问题讨论】:

【参考方案1】:

感谢@cherryblossom 的解决方案:

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void)
  ? I
  : never

// --------------------------------------------------
  
type MyEvent =
|  type: 'hello', payload:  
|  type: 'start', payload:  date: Date  


type On<Event> = UnionToIntersection<
  Event extends  type: infer EventType, payload: infer EventPayload 
    ? (type: EventType, callback: (payload: EventPayload) => void) => void
    : never
>

const init_on = (): On<MyEvent> => 
const on = init_on()

// OK
on('hello', (payload: ) => )
on('start', (payload:  date: Date ) => )

// ERROR (that is OK)
on('hello', (payload:  date: Date ) => )
on('bad-event', (payload: ) => )

Playground

【讨论】:

以上是关于从类型联合定义打字稿函数签名[重复]的主要内容,如果未能解决你的问题,请参考以下文章

打字稿重复功能实现

类型的打字稿传播运算符[重复]

打字稿:你如何用布尔或回调函数定义联合类型?

打字稿将联合转换为交集[重复]

字符串枚举类似于打字稿中的类型[重复]

函数的打字稿联合/交集类型