簡體   English   中英

Typescript 模板文字類型來自 object 數組

[英]Typescript template literal type from object array

const source = [
  { group: 'first', key: 'A' },
  { group: 'first', key: 'B' },
  { group: 'second', key: 'A' }
] as const;

type DerivedGroupKeys = `${typeof source[number]['group']}.${typeof source[number]['key']}`;
//gives "first.A" | "first.B" | "second.A" | "second.B"
type HardCodedGroupKeys = 'first.A' | 'first.B' | 'second.A';
//gives "first.A" | "first.B" | "second.A"

我希望DerivedGroupKeysHardCodedGroupKeys相同(沒有硬編碼)。 我快到了,但它為我提供了組和鍵的所有可能組合,而不僅僅是數組中定義的組合。 這可能嗎?

Template Literal Types的文檔說:

當在插值 position 中使用聯合時,類型是每個聯合成員可以表示的每個可能的字符串文字的集合:

為了克服這個問題,您可以將 map 每個數組元素分開,而不是映射聯合。

const source = [
  { group: 'first', key: 'A' },
  { group: 'first', key: 'B' },
  { group: 'second', key: 'A' }
] as const;

type ToLiteral<T> = 
  T extends {group: infer G, key: infer K} ? 
    G extends string ? 
      K extends string ? `${G}.${K}` : never 
    : never 
  : never;

type SourceElemsType = typeof source[number]
type SourceElesLiterals = ToLiteral<SourceElemsType>

這種行為是預期的, 引用手冊:

對於模板文字中的每個插值 position,聯合交叉相乘:

你想要什么是可能的,但需要幾個額外的步驟。 如果你考慮一下,當你用number索引一個元組時,結果類型可以是任何類型的元組成員(因此,聯合)。 您需要將索引類型縮小為數字文字:如果您使用文字 N 索引元組,則結果類型只能是元組的第 N 個成員的類型(因此,沒有聯合)。

首先,我們可以得到元組索引的並集:

type Indices<A> = Exclude<keyof A, keyof any[]>;

接下來,只需從元組創建一個映射類型,其中“鍵”作為元組索引,“值”作為所需的 output。 最后,只需使用元組索引對映射類型進行索引:

type DerivedGroupKeys = { [ I in Indices<typeof source> ] : `${typeof source[I]['group']}.${typeof source[I]['key']}` }[Indices<typeof source>];

暫無
暫無

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

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