【问题标题】:Typescript: how do I build an interface containing both an object and a string index type?Typescript:如何构建包含对象和字符串索引类型的接口?
【发布时间】:2022-06-28 23:37:02
【问题描述】:

我需要描述一个接口,其中:

  1. 具有“billingAddress”键的属性的值是具有特定属性的对象,并且
  2. 具有任何其他键的属性具有字符串值。

我试过了:

interface DoesNotWork {
  [key: string]: string;
  billingAddress?: {
    foo: string;
  }
}

Typescript 抱怨 Property 'billingAddress' of type '{ foo: string; } | undefined' is not assignable to 'string' index type

很公平:当 DoesNotWork.billingAddress 被定义时,Typescript 将不知道是否应该为它分配 stringobjectundefined

如何以 Typescript 可以理解的方式描述界面?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    使用有区别的联合,这样你就可以混合搭配。

    interface DoesNotWork {
      billingAddress?: {
        foo: string;
      };
    }
    
    const foo: DoesNotWork | { [key: string]: string } = {
      billingAddress: { foo: "value" },
      key: "value"
    };
    

    【讨论】:

    • 似乎工作得很好!我也加入了一个类型定义: type Customer = DoesNotWork | { [键:字符串]:字符串 }; const foo: Customer = ...
    【解决方案2】:

    使用 索引签名,因为确切的 propertyName 在编译时是未知的,但数据的一般结构是已知的,创建了一个单独的接口,以适应这些数据,然后组合接口以实现所需的对象结构,应该有助于解决您的问题使用联合类型扩展以增加灵活性预期的值

    这是因为在尝试在同一界面中定义不同的字段时,您必须满足选项,除了 索引签名字段之外的其他字段的不同(值)

    演示代码

    //composition approach(1)
    interface BillingAddress{
      foo: string;
    }
    
    interface DoesNotWork{
      [key: string]: string;
    }
    
    interface ComposedInterface{
      indexSignature: DoesNotWork,
      billingAddress? : BillingAddress,
    }
    
    
    //extending value fields using unions approach(2)
    interface BillingAddress{
      foo: string;
    }
    
    interface DoesNotWork{
       [key: string]: string | BillingAddress;
       billingAddress: BillingAddress;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 1970-01-01
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      相关资源
      最近更新 更多