0

我正在尝试使用 Telegraf (4.6.0) 类型,但在探索可能的消息属性时遇到了问题。

这是我现在要做的:

import { Telegraf, Context } from 'telegraf'

const myBot = new Telegraf(myToken)
listenerBot.on('message', (ctx: Context) => {
    const {
        text,
        forward_from_chat, forward_from_message_id,
        photo, caption, caption_entities,
        // what it will contain if there's a video? audio? document? ...
    } = ctx.message as any
    // do stuff with message
}

由于消息可以是各种类型(在非 TS 和 TS 意义上),当我输入ctx.message.IDE(在我的情况下为 VS Code)时,我只建议始终在消息对象中的道具(如message_id)。是的,我可以做类似的事情

if('text' in ctx.message) {
    // do stuff with ctx.message.text
}

但这并不能帮助我探索道具可以ctx.message容纳什么。我可以想象一种 hacky 方式

class ExploredContext = ExploreProps<Context> → gives a class similar to Context,
  but all possible props are non-optional

...
(ctx as ExploredContext).message._ // cursor here, IDE shows possilbe props
(ctx.message as ExploredMessage)._ // or like this

但我既不知道如何实现诸如ExplorePropshelper 之类的东西(我只知道实用程序类型),也不知道任何更好的、非 hacky 的方法来获得它(比如一些打字稿和/或 IDE 的配置)。

你能建议一种实现方法ExploreProps或更好的方法来探索可能的道具吗?

(在 Telegraf 的上下文中,我也在一个问题中过,但不考虑 Telegraf 本身,一致的解决方案会有所帮助)

4

1 回答 1

2

You can flatten a union using StrictUnion as defined here This type will basically add the missing members to all union constituents with the type undefined. This will allow de-structuring to suggest all members from any constituent, but each member that is not present in all union constituents will also contain undefined (which is probably for the best from a type-safety perspective)

import { Telegraf, Context } from 'telegraf'

type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> = T extends any ? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, undefined>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>


const myToken = ""
const myBot = new Telegraf(myToken)
myBot.on('message', (ctx: Context) => {
    const {
        text,
        forward_from_chat, forward_from_message_id,
        photo, caption, caption_entities,
        
    } = ctx.message as StrictUnion<Context['message']>
})

Playground Link

于 2022-02-17T09:28:06.290 回答