如何将动态密钥传递到接口描述的对象中?

时间:2017-05-05 16:25:25

标签: typescript

我有一个相当直接的json对象,它有两个不同的键“已选中”和“未选中”。

{
  "checked" : {
    "trClass": ",
    "text": "Select all",
    "icon": "fa fa-square-o"
  },
  "unchecked": {
    "trClass": "success",
    "text": "Deselect all",
    "icon": "fa fa-check-square"
  }
}

我已将此对象描述如下:

interface CheckProps {
  trClass: string;
  test: string;
  icon: string;
}
interface CheckJson {
  checked: CheckProps;
  unchecked: CheckProps;
}

现在,在我的代码中,“checked”或“unchecked”键将动态传递,并且我不断收到“隐式有任何类型”错误。 $ button元素有一个名为“state”的数据属性,它将被“检查”或“未选中”,因此它将是一个有效的选择器,但我该如何告诉TypeScript呢?

以下是相关代码:

function toggleAllCheckableRows(e: JQueryEventObject){
  const $button: JQuery = $(e.target);
  const json: CheckJson = $button.data('json');
  const state: string = $button.data('state');
  const oppositeSelector: string = $button.data('state') === 'checked' ? 'unchecked' : 'checked';

  const currentState = json[state]; //Elementy immplicity has 'any' type because type 'CheckJson' has no index signature
  const oppositeState = json[oppositeSelector]; //Elementy immplicity has 'any' type because type 'CheckJson' has no index signature
}

1 个答案:

答案 0 :(得分:2)

interface CheckJson {
  checked: CheckProps;
  unchecked: CheckProps;
}

const oppositeSelector = Math.random() % 2 > 0 ? 'unchecked' : 'checked';

declare const json: CheckJson;
json[oppositeSelector];

并非您收到该错误的原因是因为您在oppositeSelector上使用了无意义的,不必要的类型注释。你说它是string,但编译器推断类型为'checked' | 'unchecked'

让编译器完成其工作并避免注释具有初始值设定项的变量,除非出现--noImplicitAny错误。在这种情况下,只需添加更正特定错误所需的类型注释。 通过注释所有内容,我们无法利用TypeScript的一些最重要的好处。

现在是state变量

const state: string = $button.data('state');

$.fn.data的返回类型为any,因此我们可以将注释更改为'checked' | 'unchecked'

const state: 'checked' | 'unchecked' = $button.data('state');

但这不是最具可读性,因为它很详细,而且也没有明确地从any进行分配。

为了清楚说明发生了什么,我们可以写

const state = <'checked' | 'unchecked'>$button.data('state');

更清楚但仍然很尴尬。

通过声明. date('state')返回的值的类型,我们可以做得更好。

interface JQuery {
  data(key: 'state'): 'checked' | 'unchecked';
}

const state = $button.data('state');

谢谢kimamula,感谢您提供正确有用的评论