【问题标题】:How to type accessing deep object properties - getting object keys dynamically如何键入访问深层对象属性 - 动态获取对象键
【发布时间】:2019-12-06 19:11:42
【问题描述】:

我想根据提供的键名正确键入以访问对象属性。我想获取下一级对象的键。

我有以下对象,我想从中访问一些数据:

const source = {
  sth: {
    EXAMPLE: 'this is my example'
  },
  another: {
    TEST: 'this is my test value'
  }
};

访问函数:

function getMessage(context : keyof typeof source, msgKey: string) : string {

    if(msgKey in source[context]) {
      return source[context][msgKey]
    }
}

keyof typeof source 我正在获得一级密钥 - 就像一个魅力。

如何获得较低级别的密钥? msgKey: string 当然会出错:

元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“{示例:字符串; } | {测试:字符串; }'。 在类型“{ 示例:字符串; } | {测试:字符串; }'

当然,通过getMessage('sth', 'EXAMPLE')我想得到'this is my example'

【问题讨论】:

    标签: typescript


    【解决方案1】:

    根据编译提示

    在类型 '{ 示例:字符串; } | {测试:字符串; }'

    您需要为source的属性指定索引签名:

    interface Source {
      [key: string]: {  // First level
        [key: string]: string; // Second level
      }
    }
    
    const source: Source = {
      sth: {
        EXAMPLE: 'this is my example'
      },
      another: {
        TEST: 'this is my test value'
      }
    };
    

    现在您甚至不需要为第一级编写keyof typeof source,因为它已经从Source 接口中隐含了:

    function getMessage(context: string, msgKey: string): string {
      if(msgKey in source[context]) {
        return source[context][msgKey]
      }
    }
    

    更深层次的层次

    据我了解,没有办法为任何动态嵌套级别指定索引签名,因此您必须为每个级别明确指定它们。但是,您可以使用泛型使事情变得更容易:

    type Indexed<T> = {
      [key: string]: T;
    }
    
    const source: Indexed<Indexed<string>> = {
      sth: {
        EXAMPLE: 'this is my example'
      },
      another: {
        TEST: 'this is my test value'
      }
    };
    

    当您的对象具有三个或更多级别的嵌套时,这不是最优雅的阅读方式,但它是一个选项:

    const source: Indexed<Indexed<Indexed<Indexed<string>>>> = {};
    

    【讨论】:

    • 您绝对正确,我也应该输入我的来源。无论如何,解决方案编译器仍然会发出警告,并且我正在失去第一级的自动完成功能 (typescriptlang.org/play/#code/…)
    • 这是真的,因为函数不知道返回的元素是字符串还是另一个索引对象。我会更正答案中的类型。
    • 谢谢你,Matei,这在某种程度上解决了我的问题。无论如何,我仍然很好奇是否有可能获得更深层次的动态密钥(就像我对第一级所做的那样 keyof typeof source
    猜你喜欢
    • 2021-11-27
    • 2021-11-23
    • 2011-06-15
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多