【问题标题】:How to create an interface with an unknown amount of string properties and one specific property with number type?如何创建一个具有未知数量的字符串属性和一个具有数字类型的特定属性的接口?
【发布时间】:2021-08-20 10:48:10
【问题描述】:

我有一个对象,其中包含未知数量的错误消息和一个带有类型编号的属性。如何为这个对象创建一个接口?

  interface IFormErrors {
    [key: string]: string; // So here is an unknown amount of strings
  }

  const initialFormErrors: IFormErrors = {
    nameErr: "",
    emailErr: "",
    linkErr: "",
    errorCounter: 0,
  };

【问题讨论】:

  • 类型编号的属性是否始终为errorCounter 键或可以是任何键?
  • 是的,总是errorCounter

标签: javascript typescript object interface


【解决方案1】:

准确实现您正在寻找的方法是使用交叉类型:

  type IFormErrors = { errorCounter: number } & {
    [key: string]: string; // So here is an unknown amount of strings
  }

  const initialFormErrors: IFormErrors = {
    nameErr: "",
    emailErr: "",
    linkErr: "",
    errorCounter: 0,
  };

这是一种解决方法,因为一旦您定义了索引签名,Typescript 就不允许您拥有其他类型的属性。推荐的方法是使用嵌套索引签名来避免该问题:

interface IFormErrors {
  errorCounter: number;
  // you can name this property whatever you like, `errors` was just
  // what I came up with
  errors: { 
    [key: string]: string; // So here is an unknown amount of strings
  }
}

我建议阅读 Typescript Deep Dive gitbook 的这一部分,以了解有关如何有效使用索引签名的更多信息:https://basarat.gitbook.io/typescript/type-system/index-signatures#declaring-an-index-signature

【讨论】:

    【解决方案2】:

    可行,但有一些限制:

    interface IFormErrors {
        [key: string]: string; // So here is an unknown amount of strings
    }
    
    type Result = IFormErrors & {
        errorCounter: number;
    }
    
    const merge = <T, U>(a: T, b: U) => ({ ...a, ...b })
    const build = (obj: IFormErrors, errorCounter: number) => merge(obj, { errorCounter })
    
    const result = build({ a: '2' }, 5)
    
    const anyProperty = result.sdf // string
    const numberProperty = result.errorCounter // number
    
    
    
    /**
     * But you are unable to create literal type
     */
    const y: Result = { // error
        a: '23',
        errorCounter: 42
    }
    

    result 变量具有 Result 类型 - 这正是您想要的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-01
      • 2019-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多