我是打字稿新手,对此有一个疑问,我似乎无法以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函数。
我要离开这里吗?
答案 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
,因此根据传递的字符串文字隐式选择MyActionBase
或MyActionA
。
MyActionB