我有以下資料結構:
const data = [{
value: 'value',
label: 'Label',
children: [
{
value: 'value.1',
label: 'Label.1',
children: [{
value: 'value.1.1',
label: 'Label.1.1',
}],
},
{
value: 'value.2',
label: 'Label.2',
children: [{
value: 'value.2.1',
label: 'Label.2.1',
}],
}
],
},{
value: 'value2',
label: 'Label2',
}] as const;
data我的目標是基于(編輯器)自動完成生成以下元組:
[parent, children, childrenOfChildren]
和:
parent = 'value' | 'value2';
children = if parent === 'value' ? 'value.1' | 'value.2'; // The comment below explain the flow
// ['value' | 'value2'] > 'value' > ['value', 'value.1' | 'value.2'] > 'value.1' > ['value', 'value.1', 'value.1.1' | 'value.1.2'] > 'value.1.1' > ['value', 'value.1', 'value.1.1']
...
因此,元組應該是動態的,基于物件中表示資料鍵的子陣列的深度。選擇看起來像這樣:'value'
['value' | 'value2', 'value.1' | 'value.2' ]從哪里'value.1' | 'value.2'可以選擇。
選擇 'value' 然后選擇 'value.1' 將是:
['value', 'value.1', or (value.1).children.value ].
到目前為止我所做的:
- 將資料轉換為常量:
data = [...] as const; - 通用型別
declare const generateTuple: <T extends Record<K, PropertyKey | T[]>, K extends keyof T>(
objArray: readonly T[],
property: K,
) => [T[K]];
這成功地為給定的鍵生成型別,但不是為深度。我找不到遞回生成回傳元組型別的方法:
[T[K], generateTuple(T[K]['children'], k)]

uj5u.com熱心網友回復:
我的解釋是你有一個data擴展型別的值,Data定義如下:
type Data = readonly DataElement[];
interface DataElement {
value: string;
label: string;
children?: Data;
}
并且您想定義一個型別函式type DataPaths<T extends Data>,其計算結果為元組型別的聯合,表示通過樹的每個可能的屬性路徑。正如您的問題中給出的那樣,這應該類似于:valuedata
type ValidPaths = DataPaths<typeof data>
// type ValidPaths = [] | ["value"] | ["value", "value.1"] |
// ["value", "value.1", "value.1.1"] | ["value", "value.2"] |
// ["value", "value.2", "value.2.1"] | ["value2"]
我不清楚您是否真的只想要一直到樹結構的葉子節點的路徑,或者您是否可以接受在葉子之前結束的路徑。我會選擇后者,所以這就是為什么上面包含["value"]以及空的 tuple []。
這是實作它的一種方法:
type DataPaths<T extends Data | undefined> =
[T] extends [Data] ? DataElementPaths<T[number]> : []
type DataElementPaths<T extends DataElement> = [] | (
T extends DataElement ? [T["value"], ...DataPaths<T["children"]>] : never
)
這個想法是DataPaths作用于(可能undefined)型別陣列DataElement,同時DataElement作用于一個DataElement型別(或它們的聯合)。該DataPaths<T>型別被實作為回傳DataElementPaths所有陣列元素,T如果它是一個陣列或空元組,否則(如果它是undefined)。
并且DataElementPaths只是將 的屬性(通過可變元組型別)添加到遞回評估屬性的結果中。valueDataElementDataPathschildren
請注意,空元組被并入到DataElementPaths無論如何 (as [] | );的結果中。正是這個允許部分路徑;如果你洗掉了它,那么你只會得到葉子的路徑。
還要注意,為了使輸入聯合成為輸出聯合,這被實作為分布式條件型別;因此T extends DataElement ? ... : never. 這似乎是一個無操作(我們已經知道T extends DataElement),但沒有它你只會得到一個元組而不是一個聯合。
您可以驗證實作確實為ValidPaths.
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/472034.html
