我正在努力制作一個通用的,它將遞回地修改在嵌套遞回資料結構中找到的所有元素。這是我的資料結構的示例。使用此遞回資料定義,任何帖子都可以有無限數量的帶有回復的評論。
type Post = {
user: string,
content: string,
comments: Comment[],
reactions: Reaction[],
}
type Comment = {
user: string,
content: string,
replies: Comment[],
}
type Reaction = {
user: string,
reaction: "laugh" | "cry" | "smile",
}
我想要的是一個通用包裝器,我可以將它與這些以及任何其他可以用其他user東西替換每個欄位的資料型別一起使用。我可以為頂層做到這一點:
type UserFilled<T> = Omit<"user", T> & { user: { id: string, name: string }}
但這只會改變userPost的欄位。我還希望它向下爬取并替換user每個評論的更改欄位,如果有更多欄位,則用于反應、喜歡或任何其他帶有 a 的結構user。
我已經看到有關遞回省略某些內容的答案,但我無法使用聯合將修改后的屬性重新添加,我想知道是否有更直接的方法可以做到這一點,而不僅僅是省略而且替換欄位?
例如,使用泛型我希望能夠做到這一點:
const post: Post = {
user: "1234",
content: "this is a post",
comments: [{
user: "3456",
content: "I agree",
replies: [{
user: "1234",
content: "thanks",
}],
}],
reactions: [{
user: "5678",
reaction: "smile",
}],
};
const postWUserInfo: UserFilled<Post> = {
user: { id: "1234", name: "Bob" },
content: "this is a post",
comments: [{
user: { id: "3456", name: "Jim" },
content: "I agree",
replies: [{
user: { id: "1234", name: "Bob" },
content: "thanks",
}],
}],
reactions: [{
user: { id: "5678", name: "Jim" },
reaction: "smile",
}],
};
uj5u.com熱心網友回復:
您可以創建一個 DeepReplace 實用程式來遞回檢查和替換密鑰。另外我強烈建議只替換值并確保密鑰保持不變。
// "not object"
type Primitive = string | Function | number | boolean | Symbol | undefined | null
// If T has key K ("user"), replace it
type ReplaceKey<T, K extends string, R> = T extends Record<K, unknown> ? Omit<T, K> & Record<K, R> : T
// Check and replace object values
type DeepReplaceHelper<T, K extends string, R, ReplacedT = ReplaceKey<T, K, R>> = {
[Key in keyof ReplacedT]: ReplacedT[Key] extends Primitive ? ReplacedT[Key] : ReplacedT[Key] extends unknown[] ? DeepReplace<ReplacedT[Key][number], K, R>[] : DeepReplace<ReplacedT[Key], K, R>
}
// T = object, K = key to replace, R = replacement value
type DeepReplace<T, K extends string, R> = T extends Primitive ? T : DeepReplaceHelper<T, K, R>
// Define new type for "user" key
interface UserReplacement {
id: string
name: string
}
type UserFilled<T> = DeepReplace<T, "user", UserReplacement>
Typescript Playground 分步說明
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/405746.html
標籤:
