代码之家  ›  专栏  ›  技术社区  ›  YakovL Naresh Kumar Nakka

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

  •  0
  • YakovL Naresh Kumar Nakka  · 技术社区  · 4 年前

    我正在尝试使用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代码)中,我只建议使用 总是 在消息对象中(如 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 )我也不知道有什么更好的、非黑客的方法来实现这一点(比如typescript和/或IDE的一些配置)。

    你能建议一种实施方法吗 ExploreProps 还是探索可能道具的更好方法?

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

    0 回复  |  直到 4 年前
        1
  •  2
  •   Titian Cernicova-Dragomir    4 年前

    可以使用展开并集 StrictUnion 如定义 here 此类型基本上将丢失的成员添加到具有该类型的所有联合组成部分 undefined 。这将允许取消结构,以建议任何组成部分的所有成员,但并非所有工会组成部分的每个成员也将包含 未定义的 (从类型安全的角度来看,这可能是最好的)

    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

    推荐文章