簡體   English   中英

TypeScript:在編譯時使用枚舉作為接口/對象鍵的過濾器

[英]TypeScript: Use Enum as filter for Interface/Object keys in Compile Time

我有一個enum (字符串到字符串),其中包含一個function有效鍵。 我還有一個object (或interface ),它在枚舉中有一些鍵,有些沒有。

如何將函數的參數設置為僅來自enum中存在的interface的鍵 (例如 Pick、Extract、Intersection,無論您想怎么稱呼它們,都可以正確保留密鑰。)

例子

以下示例與我的項目無關,但適當地展示了我的需要。

假設enuminterface如下:

enum PromotableProperties {
  SALARY = "salary",
  SIGNON_BONUS = "signonBonus",
  ANNUAL_BONUS = "annualBonus",
}

interface IExistingEmployee {
  id:           number;
  name:         string;
  salary:       number;
  signonBonus:  number;
  age:          number;
}

現在實際的代碼是:

type ValidPropsOf<ENUM_T, OBJ_T> = ...; // I want this!

type PromotablePropsForExistingEmployee = ValidPropsOf<PromotableProperties, IExistingEmployee>;


function promoteEmployeeBy(
  emp: IExistingEmployee,
  prop: ValidPropsOf<PromotableProperties, IExistingEmployee>,
  byValue: number,
): void {
  emp[prop] += byValue;
  console.log(`${emp.name}'s ${prop} is increase by ${byValue}'`);
}

const goodOldJohn: IExistingEmployee = {
  id: 5,
  name: "john",
  salary: 20000,
  signonBonus: 1000,
  age: 25,
};

promoteEmployeeBy(goodOldJohn, PromotableProperties.SALARY, 100);
promoteEmployeeBy(goodOldJohn, PromotableProperties.ANNUAL_BONUS, 100); // Error
promoteEmployeeBy(goodOldJohn, "age", 100); // Error

注意,第二個函數調用失敗,因為ANNUAL_BONUS不在存在IExistingEmployee和第三個電話應該失敗,因為agePromotableProperties

我需要的

... 是type ValidPropsOf<ENUM_T, OBJ_T> = ...的實用程序類型,返回存在於枚舉(作為值)和對象/接口中的鍵。

TS游樂場

在這里

什么沒用

我認為Extract (來自TS 官方實用程序類型)應該可以工作,但我無法讓它工作。

我還嘗試了Pick和我知道的兩個已知 TS Utility 存儲庫中的許多其他實用程序類型,但都沒有幫助。

  1. https://github.com/piotrwitek/utility-types
  2. https://github.com/krzkaczor/ts-essentials

什么起作用了

對我Exclude是雙重Exclude 它是:

type ValidPropsOf<ENUM_T, OBJ_T> = Exclude<ENUM_T, Exclude<ENUM_T, keyof OBJ_T>>;

顯然Exclude正確地保留了密鑰(並且不會積極地概括單個密鑰)。 所以從enum我取出object不存在的那些(稱它們為badProps ),好的將是goodProps = allProps - badProps

它完全保留了單個密鑰。 您可以通過將鼠標懸停在此工作 TS Playground Link 中函數中的類型上來測試它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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