簡體   English   中英

訪問在 typescript 接口定義中定義的值

[英]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 ,從而選擇MyActionAMyActionB隱含根據在傳遞的字符串文字上。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM