【问题标题】:What is the best way to manage static keys? (TS)管理静态密钥的最佳方法是什么? (TS)
【发布时间】:2018-02-16 07:11:45
【问题描述】:

在我的应用程序中,我总是遇到使用一些预定义且根本不会更改的键的问题 - 即它们是硬编码的。而且我不知道哪个选项是最好的。

目前我有:

export class PermissionKeys {
  public static readonly MYKEY_NOT_ALL_SPECIFIED = 'MYKEY_NOT_ALL_SPECIFIED';
}

还有

export enum MyKey {
  MYKEY_NOT_ALL_SPECIFIED = <any>'MYKEY_NOT_ALL_SPECIFIED',
}

在最终代码中,我想比较 this.checkKey=MYKEY_NOT_ALL_SPECIFIED 之类的内容。对于enum,我需要始终附加.toString()。使用readonly 字符串,我需要指定名称和内容(始终保持完全相同)。

谁有更好的方法来管理硬编码的密钥?

【问题讨论】:

  • 只是普通的对象。没有纯静态类。没有损坏的枚举。顺便说一下,这是 TypeScript 而不是 Javascript。
  • 是的...我明白了...谢谢提示...我认为功能完全相同
  • 由于 TS 是 JS 的超集,所以大部分特性是相同的,但上下文不同。并且枚举是仅限 TS 的。您应该记住在 TS 中将如何应用类型,因此方法可能会有很大差异。
  • @ThirueswaranRajagopalan 不是真的 - 我猜 - 因为 Direction.right 需要与 "right" 进行比较 ==> 如何让字符串“正确”?

标签: typescript


【解决方案1】:

如果没有关于您的用例的更多信息,我不确定哪种方式最适合您。您可以使用字符串枚举:

export enum MyKey {
  MYKEY_NOT_ALL_SPECIFIED = 'MYKEY_NOT_ALL_SPECIFIED', // no <any>
  OTHERKEY = 'OTHERKEY',
  ETC = 'ETC'
}

class Something {
  checkKey: MyKey;
  someMethod() {
    if (this.checkKey === MyKey.MYKEY_NOT_ALL_SPECIFIED) {
      // do something
    } 
  }
}

或者,如果你不想重复自己并且知道值和键总是相等的,你可以使用一个常量普通对象:

function sameValuesAsKeys<K extends string>(...values: K[]): {readonly [P in K]: P} {
  const ret = {} as {[P in K]: P}
  values.forEach(k => ret[k] = k);
  return ret;
}

export const MyKey = sameValuesAsKeys('MYKEY_NOT_ALL_SPECIFIED', "OTHERKEY", "ETC");
type MyKey = keyof typeof MyKey;

// still works
class Something {
  checkKey: MyKey;
  someMethod() {
    if (this.checkKey === MyKey.MYKEY_NOT_ALL_SPECIFIED) {
      // do something
    } 
  }
}

这是否回答了您的问题?如果不是,请更具体地说明您的用例...显示一些您无法获得所需密钥的代码,或者您觉得自己在重复自己的地方,我会更新答案。

希望有所帮助;祝你好运!


更新 1

解释签名

function sameValuesAsKeys<K extends string>(...values: K[]): {readonly [P in K]: P}

类型参数K 是某个字符串或字符串的联合,参数values 是该类型字符串的数组。如果我调用sameValuesAsKeys("dog","cat"),TypeScript 会推断出K"dog"|"cat"sameValuesAsKeys() 的返回类型是{readonly [P in K]: P},这是一个mapped type,大致意思是“每个属性都是只读的并且值与键相同的对象”。所以如果我调用sameValuesAsKeys("dog","cat"),返回值是{readonly dog: "dog"; readonly cat: "cat"}类型。

【讨论】:

  • 是的,谢谢,这有助于防止双重命名和双重定义 - 尽管 IDE 中出现了一些其他(次要)问题。无论如何,这个解决方案的好处是直接转发变量的内容。这有助于避免双重定义。 (虽然我不得不承认我并不完全理解通用代码——ROFL)。谢谢
  • sameValuesAsKeys()的签名添加了一些解释,不知道它是否为你清除了任何东西。
  • 是的,谢谢你的额外解释——这有助于消化。也感谢您提供映射类型的链接 - 我希望将其作为 TS 的更新 :-) 我非常感谢您的帮助/帮助
【解决方案2】:

工作演示 https://es6console.com/j7ajnnma/ 。请按照步骤查看结果:

  1. 打开您的 Bowser 控制台
  2. 选择编译器 => “打字稿”
  3. 点击“转换”
  4. 点击“运行”

演示代码:

enum Direction {
    Up,
    Down,
    Left,
    Right
}

/* Trues */
var value: any = 'Right';
console.log(`'Direction[value] === Direction.Right' => ${Direction[value] === Direction.Right}`);

value = 3;
console.log(`'value === Direction.Right' => ${value === Direction.Right}`);

/* False */
value = 'Up';
console.log(`'Direction[value] === Direction.Right' => ${Direction[value] === Direction.Right}`);

value = 1;
console.log(`'value === Direction.Right' => ${value === Direction.Right}`);

【讨论】:

  • 我个人喜欢这个解决方案,但不幸的是我无法使用它,因为我需要以封装的方式在其他地方处理字符串的相等性,即我需要字符串值本身:-/
猜你喜欢
  • 2017-04-20
  • 2013-01-19
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2020-10-05
相关资源
最近更新 更多