【问题标题】:Typescript: access an object property with square bracket notation and variable打字稿:使用方括号表示法和变量访问对象属性
【发布时间】:2022-01-18 08:57:00
【问题描述】:

在 TypeScript 中使用 [ ] 表示法访问 Javascript 对象并使用一个变量(我们最初不确定它的值)的正确方法是什么,该变量评估为带有括号的字符串来访问对象属性,即 @ 987654322@

以下代码错误符合预期,因为我们在 x 中有一个未知值,因此我们无法确定它是 myDictionary 的键(但是,这不完全是错误,请参阅代码注释):

const myDictionary = {
  key1: 'String 1',
  key2: 'String 2',
  key3: 'String 3',
};

const possibleValuesOfX = [
  'key1',
  'notAKey1',
  'key2',
  'notAKey2',
  'key3',
  'notAKey3',
];

// simulating a random value that could be a possible key of myDictionary
const x =
  possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];

// The following errors: No index signature with a parameter of type 'string' was found on type '{ key1: string; key2: string; key3: string; }'.ts(7053)
const decode = myDictionary[x]; 

所以我尝试以下操作,认为在尝试使用x 访问myDictionary 之前,我正在检查以确保xmyDictionary 的键

const myDictionary = {
  key1: 'String 1',
  key2: 'String 2',
  key3: 'String 3',
};

const possibleValuesOfX = [
  'key1',
  'notAKey1',
  'key2',
  'notAKey2',
  'key3',
  'notAKey3',
];

const x =
  possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];

let decode: string;
if (x in myDictionary) {
  // Still produces the same error as above
  decode = myDictionary[x];
}

这并不能阻止错误。

现在我可以使用 const myDictionary: { [key: string]: string } 停止错误,但这也会停止使用 myDictionary 的自动完成功能,并且我所看到的几乎没有其他内容。

要保持自动完成并停止错误,我可以执行以下操作:

type myDictionaryKeys = 'key1' | 'key2' | 'key3';
const myDictionary: Record<myDictionaryKeys, string> = {
  key1: 'String 1',
  key2: 'String 2',
  key3: 'String 3',
};

const possibleValuesOfX = [
  'key1',
  'notAKey1',
  'key2',
  'notAKey2',
  'key3',
  'notAKey3',
];

const x =
  possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];

let decode: string;
if (x in myDictionary) {
  decode = myDictionary[x as myDictionaryKeys];
}

但这仍然感觉'hacky'并且过于冗长,因为我正在投射x as myDictionaryKeys以消除错误并且必须在myDictionary对象和myDictionaryKeys类型中键入两次键。

是否有“正确”的方式来做到这一点,或者更清洁的方式?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    编辑:针对your comment 中的问题更新了示例。


    您可以使用type predicate 通知编译器该值是字典中的键,例如本例中的isDictionaryKey 函数:

    TS Playground

    function isDictionaryKey <T>(
      dictionary: T,
      str: string,
    ): str is keyof Omit<T, number | symbol> {
      return str in myDictionary;
    }
    
    const myDictionary = {
      key1: 'String 1',
      key2: 'String 2',
      key3: 'String 3',
    };
    
    const possibleValuesOfX = [
      'key1',
      'notAKey1',
      'key2',
      'notAKey2',
      'key3',
      'notAKey3',
    ];
    
    const x = possibleValuesOfX[Math.floor(Math.random() * possibleValuesOfX.length)];
    
    let decode: string;
    if (x && isDictionaryKey(myDictionary, x)) {
      x; // "key1" | "key2" | "key3"
      decode = myDictionary[x];
    }
    

    【讨论】:

    • 谢谢,有没有办法让isDictionaryKey() 通用以与任何传入的字典一起使用,或者您是否必须为要使用的每个字典创建其中一个函数?跨度>
    • @DanielGranger 查看我的更新答案。
    猜你喜欢
    • 1970-01-01
    • 2016-04-16
    • 2020-10-25
    • 2015-03-31
    • 1970-01-01
    • 2022-01-05
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多