簡體   English   中英

包含用作接口鍵的 keyof 的模板文字

[英]Template literal containing keyof used as an interface key

給定一個簡單的界面:

interface Schedule {
  interval: "month" | "day";
  price: number;
}

我可以構造一個模板文字類型(使用ts4.4 ):

type PrefixedScheduleKey = `schedule__${keyof Schedule}`; // "schedule__interval" | "schedule__price"

假設有一些這樣的接口,我想合並(基本上展平)它們的前綴、模板文字鍵,最終得到:

interface Metadata {
  foo: string;
  bar: string;
  // computed 
  schedule__interval: "month" | "day";
  schedule__price: number;
  ...
}

我應該如何聲明這樣的接口鍵?

interface Metadata {
  [key: PrefixedScheduleKey]: any
}

// throws 
// An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.(1337)

interface Metadata {
  [key in `schedule__${keyof Schedule}`]: any 
}

// leads to
// A computed property name must be of type 'string', 'number', 'symbol', or 'any'.(2464)
// Member '[key in `schedule__${keyof' implicitly has an 'any' type.(7008)

這里是游樂場

順便說一句, 在 github 上建議使用type而不是interface但這不起作用,因為我的Metadata接口已經擴展了另一個接口,但我試圖保持示例簡單。

這不可能直接在接口上執行,如此處所述: Typescript: Mapped types with Interface

到目前為止,在 TypeScript 中(從 2.7.2 版開始),接口中的聯合類型簽名是不允許的,而是應該使用映射類型(正如您正確使用的那樣)。

文檔

但是,您可以使用任意接口和映射類型之間的交集類型來實現這一點, 如您提到的原始 GitHub 問題(“將其他成員移動到與交集類型組合的單獨對象類型”)。 您還可以使用as關鍵字有效地內聯您的PrefixedScheduleKey模板文字類型,同時保留您的Key足夠長的時間以引用Schedule[Key] 沒有理由不能對其他帶前綴的類型執行相同的操作,無論是在相同的映射元數據類型中還是在您稍后與之相交的相鄰元數據類型中。

作為參考,當在映射類型中用作類型變量時, key大寫為Key ,如映射類型手冊頁中所示。

interface BareMetadata /* extends ArbitraryType */ {
  foo: string;
  bar: string;
}

type ScheduleMetadata = {
  [Key in keyof Schedule as `schedule__${Key}`]: Schedule[Key];
}

type MergedMetadata = BareMetadata & ScheduleMetadata;

const example: MergedMetadata = {
  foo: "one",
  bar: "two",
  schedule__interval: "month",
  schedule__price: 9.99
};

游樂場鏈接

您甚至可以讓interface擴展一個類似對象的type ,這可能會幫助您避免顯式交集:

interface MergedMetadata extends BareMetadata, ScheduleMetadata {}
// or
interface Metadata extends ScheduleMetadata {
  foo: string;
  bar: string;
}

游樂場鏈接

暫無
暫無

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

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