[英]Accessing a value defined in a typescript interface defintion
我是打字稿的新手,有一個關於它的問題,我似乎無法以 Googleable 的方式提出。
假設我定義了這個接口:
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”,其“類型”為“MyActionA”或“MyActionB”。 我想將此“類型”用作常量值,並將其傳遞給實際的 takeEvery 函數。
我是不是離基地很遠?
要定義值'myValue'
而不是類型'myValue'
,您可以使用enum
而不是interface
:
enum MyEnum {
myField = "myValue"
}
const value = MyEnum.myField;
不編譯的原因是因為ActionType
是所謂的類型參數,它是傳遞給<...>
任何東西,而不是(...)
,它們被稱為值參數,或者更簡單地說,只是參數.
因為它是一個類型而不是一個值,所以 TypeScript 從編譯的 JavaScript 輸出中刪除了它的定義,這就是為什么即使它是一個類型,你也會收到它被用作值的錯誤。 因此,當編譯器運行時,它會留下一個未定義的ActionType
引用,該引用未在 JavaScript 中的任何地方聲明。
現在,為了解決你的問題,我還是建議使用enum
,並通過actionType
的值參數,讓ActionType
推斷其類型類型參數,並用它來聲明局部類型MyAction
擴展MyActionBase
,從而選擇MyActionA
或MyActionB
隱含根據在傳遞的字符串文字上。
import { Action } from 'redux'
enum MyActionType {
MyActionA = 'MyActionA',
MyActionB = 'MyActionB'
}
interface MyActionA extends Action {
typeString: MyActionType.MyActionA,
payload: {
// omitted
}
}
interface MyActionB extends Action {
typeString: MyActionType.MyActionB,
payload: {
// omitted
}
}
type MyActionBase =
| MyActionA
| MyActionB
function* typeSafeTakeEvery<ActionType extends MyActionType>(actionType: ActionType, saga: Function) {
type MyAction = MyActionBase & { typeString: ActionType }
yield takeEvery(actionType, function*(action: MyAction) {
yield saga(action);
});
}
// Usage
typeSafeTakeEvery(MyActionType.MyActionA, ...)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.