访问在打字稿界面定义中定义的值

时间:2018-08-31 21:12:15

标签: typescript redux interface redux-saga value-type

我是打字稿新手,对此有一个疑问,我似乎无法以Google的方式摆姿势。

假设我定义了此接口:

interface MyInterface {
  myField: "myValue"
}

我希望能够编写以下代码行:

const value = MyInterface.myField; // expect value to equal "myValue"

这不能编译,但是我想知道是否有某种方法可以实现此行为。由于myField的值是在打字稿编译时定义的,我相信这应该是可能的。但是我不知道该怎么做。

任何建议表示赞赏。谢谢!

更新

我想我需要提供更多信息。我通过遵循本文来尝试减少样板并维护redux应用程序中的类型安全:

https://medium.com/@resir014/a-type-safe-approach-to-redux-stores-in-typescript-6474e012b81e

我也在使用redux-saga,本质上我试图创建一个类型安全的takeEvery。

假设如上一篇文章所述,我有两个定义为接口的操作:

import { Action } from 'redux'

interface MyActionA extends Action {
  typeString: "MyActionA",
  payload: {
    // omitted
  }
}

interface MyActionB extends Action {
  typeString: "MyActionB",
  payload: {
    // omitted
  }
}

type MyActionBase =
  | MyActionA
  | MyActionB

是否存在一些有效的方法来编写以下内容?:

function* typeSafeTakeEvery<ActionType extends MyActionBase>(saga: Function) {
  const typeString = ActionType.typeString; // <-- I don't know how to write this line
  yield takeEvery(typeString, function*(action: ActionType) {
    yield saga(action);
  });
}

对于此通用函数的任何给定实例,它都知道ActionType的静态类型(MyActionA或MyActionB),并且它必须具有“ typeString”字段,且其“ type”为“ MyActionA”或“ MyActionB”。我想将此“类型”用作常量值,并将其传递给实际的takeEvery函数。

我要离开这里吗?

1 个答案:

答案 0 :(得分:1)

要定义 'myValue'而不是 type 'myValue',可以使用enum代替{{ 1}}:

interface

更新

之所以无法编译,是因为enum MyEnum { myField = "myValue" } const value = MyEnum.myField; 是所谓的 type 参数,它是传递给ActionType而不是<...>的任何东西,称为 value 参数,或更简单的说,就是正义参数。

因为TypeType是一个类型而不是一个值,所以TypeScript从已编译的JavaScript输出中删除其定义,这就是为什么您会得到一个错误,即使它是一个类型,它仍被用作值。因此,当编译器运行时,它会留下未定义的对(...)的引用,而该引用未在JavaScript中的任何地方声明。

现在,要解决您的问题,我仍然建议使用ActionType,并将enum作为值参数传递,让actionType类型参数推断其类型并使用它来声明扩展了ActionType的本地类型MyAction,因此根据传递的字符串文字隐式选择MyActionBaseMyActionA

MyActionB