【问题标题】:Typescript Interface, reference one instance property for dynamic second propertyTypescript 接口,为动态第二个属性引用一个实例属性
【发布时间】:2019-03-23 11:09:37
【问题描述】:

我想使用 Typescript 接口实例中的属性来计算第二个属性。我一直在研究泛型,但我还没有成功实现这一点。 :

这是一个例子

// Here I define all valid names - works fine!

type ModalNames = 'payment' | 'source'

// This interface implements all expected payloads
//  for each name 

interface ModalPayloads {
  payment: {
    plan: string
  }
  source: {
    metadataId: string
  }
}


// How do I use the instance name
//  to grab the correct payload property?
export interface ShowModalPayload {
  name: ModalNames
  modalProps?: ModalPayloads[instance.name]
}

换句话说,对于ShowModalPayload 中的给定instance,我想将modalProps 分配给从instance.name 派生的类型。 希望这是有道理的!

【问题讨论】:

    标签: javascript typescript interface typescript-types


    【解决方案1】:

    我会为此使用generics

    export interface ShowModalPayload<K extends ModalNames> {
      name: K
      modalProps?: ModalPayloads[K]
    }
    

    注意使用ModalPayloads[K] 代替ModalPayloads[instance.name]。这称为lookup type,它允许您描述m[k] 的类型,其中m 的类型为ModalPayloadsk 的类型为K

    无论如何ShowModalPayload 接口现在在K 中是通用的,它应该是ModalNames 文字之一:

    declare const smpPayment: ShowModalPayload<'payment'>;
    smpPayment.name // "payment"
    smpPayment.modalProps // {plan: string} | undefined
    
    declare const smpSource: ShowModalPayload<'source'>;
    smpSource.name // "source"
    smpSource.modalProps // {metadataId: string} | undefined
    

    我认为这些与您正在寻找的内容相对应。请注意,以下仍然是可能的:

    declare const smpWhoKnows: ShowModalPayload<ModalNames>
    smpWhoKnows.name // ModalNames
    smpWhoKnows.modalProps // {plan: string} | {metadataId: string} | undefined
    

    这可能不是您想要的,但不被禁止。不过,对于大多数用例来说,上述定义可能就足够了。

    希望对您有所帮助。祝你好运!

    【讨论】:

    • 感谢您的快速回复!我仍然收到错误 -> Type 'K' cannot be used to index type 'ModalPayloads'.
    • 我无法重现该错误。您是否提供了minimal reproducible example?如果ModalNames 的值多于keyof ModalPayloads,您将收到该错误。
    • 啊哈——一定是这样。是的,这是一个不完整的例子——让我再深入一点。谢谢!
    猜你喜欢
    • 2021-03-04
    • 2015-08-09
    • 2021-05-16
    • 1970-01-01
    • 2023-04-08
    • 2019-04-25
    • 2023-03-21
    • 2016-12-11
    • 1970-01-01
    相关资源
    最近更新 更多