我可以在 TypeScript 中获得对象所有可能属性的建议吗?

Can I get suggestions of all possible properties of an object in TypeScript?

我正在尝试使用 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 意义上),当我在 IDE 中键入 ctx.message.(在我的例子中是 VS Code)时,我只被建议在消息对象中 always 的道具(如 message_id)。是的,我可以做

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

但这对我探索什么道具可以ctx.message没有帮助。我可以想象像

这样的骇人听闻的方式
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

但我既不知道如何实现 ExploreProps 助手之类的东西(我只知道 utility types),也不知道更好的、非 hacky 的方法来获得它(比如一些配置打字稿 and/or IDE).

您能否建议一种实现方式 ExploreProps 或探索可能道具的更好方式?

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

您可以使用 StrictUnion 定义的 来展平联合体 这种类型基本上会将缺少的成员添加到类型为 undefined 的所有联合体成分中。这将允许 de-structuring 推荐来自任何组成部分的所有成员,但不存在于所有联合组成部分中的每个成员也将包含 undefined(从 type-safety 的角度来看,这可能是最好的)

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