0
votes

Tapez la fusion sécurisée des littéraux d'objets dans Typescript

Je veux fusionner deux objets dossiers (à l'aide de l'objet Sprever): xxx pré>

Je souhaite utiliser le système de type pour vous assurer qu'aucune des propriétés de la seconde objet écrase les propriétés de la première . Je ne sais pas pourquoi la solution suivante ne fonctionne pas: p> xxx pré>

Une autre version d'un an il y a que j'ai pensé travailler à l'époque avait non définie s'étends u [k] code> à la place de t [k] s'étend u [k] CODE>: P>

type UniqueObject<T extends {[K in keyof U]?: any}, U> =
    {[K in keyof U]: undefined extends T[K] ? U[K]: never}


0 commentaires

3 Réponses :


1
votes

Les deux versions sont plus ou moins équivalentes - seules les branches vraies / fastes du type conditionnel sont commutées.

La contrainte t s'étend {[k dans la touche u]?: tout} est un peu problématique: lorsque vous supprimez a dans deux , l'erreur type '{A: numéro; } 'n'a pas de propriétés en commun avec type' {B?: Toute; } est déclenché, ce qui devrait réellement être le cas de réussite.

également être aussi conscient, que le type résultant fusion ne contient pas la définition de type fusionnée des deux types . Nous pouvons changer la déclaration suivante: xxx

MAINTENANT, le compilateur Erreurs correctement, avec un double A Propriété: xxx < / Pré>

Dans ce qui suit, j'ai simplifié le type A et tout emballé dans une fonction d'assistance compacte pour contrôler les types + opérateur de répression: xxx

code de Échantillon


4 commentaires

Brillant. Merci. Oui, la modification de k étend la clé de t est la clé. J'ai ajouté 3 autres cas de test et j'ai fait un changement suggéré. N'hésitez pas à éditer à nouveau comme vous le souhaitez.


En fait, j'ai ajouté quelques types de scénarios de plus qu'il "incorrectement". Je ne peux pas comprendre un moyen de les résoudre en ce moment, car il s'agit de Keyof ({[[index: string]: numéro}) => chaîne qui correspond Tout k dans la touche u et les fait jamais .


HM, vous avez proposé de nouveaux cas ici (a perdu un peu la piste de la réponse éditée). La question initiale portait sur la fusion de deux catégories d'objets. Des objets avec un type de signature d'index explicite apportent une autre dimension. Je suggère que vous étends votre question si la réponse n'a pas vraiment satisfait vos besoins ou écrivez à la place de votre propre réponse. Acclamations!


D'accord et d'excuses, Brain V fatigué. J'ai modifié le titre de la question pour ne le faire que sur les littéraux de l'objet, j'ai remis une modification mineure (à nouveau, veuillez éditer si vous êtes en désaccord), et j'ai posé une nouvelle question ici: Stackoverflow.com/q/59689060/539490



0
votes

Essayez xxx


1 commentaires

Veuillez ajouter quelques explications à votre réponse, de sorte que d'autres puissent en apprendre d'elle



0
votes

Prendre @ Réponse de Ford04 et en expansinant pour plusieurs valeurs facultatives:

function safe_merge<
    O1,
    O2 extends { [K2 in keyof O2]: K2 extends keyof O1 ? never : O2[K2] },
    O3 extends { [K3 in keyof O3]: K3 extends keyof O1 ? never : (K3 extends keyof O2 ? never : O3[K3]) },
    O4 extends { [K4 in keyof O4]: K4 extends keyof O1 ? never : (K4 extends keyof O2 ? never : (K4 extends keyof O3 ? never : O4[K4])) },
    O5 extends { [K5 in keyof O5]: K5 extends keyof O1 ? never : (K5 extends keyof O2 ? never : (K5 extends keyof O3 ? never : ( K5 extends keyof O4 ? never : O5[K5]))) },
    O6 extends { [K6 in keyof O6]: K6 extends keyof O1 ? never : (K6 extends keyof O2 ? never : (K6 extends keyof O3 ? never : ( K6 extends keyof O4 ? never : (K6 extends keyof O5 ? never : O6[K6])))) },
    O7 extends { [K7 in keyof O7]: K7 extends keyof O1 ? never : (K7 extends keyof O2 ? never : (K7 extends keyof O3 ? never : ( K7 extends keyof O4 ? never : (K7 extends keyof O5 ? never : (K7 extends keyof O6 ? never : O7[K7]))))) },
    O8 extends { [K8 in keyof O8]: K8 extends keyof O1 ? never : (K8 extends keyof O2 ? never : (K8 extends keyof O3 ? never : ( K8 extends keyof O4 ? never : (K8 extends keyof O5 ? never : (K8 extends keyof O6 ? never : (K8 extends keyof O7 ? never : O8[K8])))))) },
    O9 extends { [K9 in keyof O9]: K9 extends keyof O1 ? never : (K9 extends keyof O2 ? never : (K9 extends keyof O3 ? never : ( K9 extends keyof O4 ? never : (K9 extends keyof O5 ? never : (K9 extends keyof O6 ? never : (K9 extends keyof O7 ? never : (K9 extends keyof O8 ? never : O9[K9]))))))) },
>(
    o1: O1,
    o2: O2 = ({} as any),
    o3: O3 = ({} as any),
    o4: O4 = ({} as any),
    o5: O5 = ({} as any),
    o6: O6 = ({} as any),
    o7: O7 = ({} as any),
    o8: O8 = ({} as any),
    o9: O9 = ({} as any),
): O1 & O2 & O3 & O4 & O5 & O6 & O7 & O8 & O9 {
    return { ...o1, ...o2, ...o3, ...o4, ...o5, ...o6, ...o7, ...o8, ...o9 }
}


const obj_1 = {1:1}
const obj_2 = {2:1}
const obj_3 = {3:1}
const obj_4 = {4:1}
const obj_5 = {5:1}
const obj_6 = {6:1}
const obj_7 = {7:1}
const obj_8 = {8:1}
const obj_9 = {9:1}


// should not error
safe_merge(obj_1)
safe_merge(obj_1, obj_2)
safe_merge(obj_1, obj_2, obj_3)
safe_merge(obj_1, obj_2, obj_3, obj_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9)


// declare objects with keys conflicting with existing objects
const obj_2_1 = {2:1, 1: 1}
const obj_2_1b = {2:1, 1: undefined}

const obj_3_1 = {3:1, 1:1}
const obj_3_2 = {3:1, 2:1}

const obj_4_1 = {4:1, 1:1}
const obj_4_2 = {4:1, 2:1}
const obj_4_3 = {4:1, 3:1}

const obj_5_1 = {5:1, 1:1}
const obj_5_2 = {5:1, 2:1}
const obj_5_3 = {5:1, 3:1}
const obj_5_4 = {5:1, 4:1}

const obj_6_1 = {6:1, 1:1}
const obj_6_2 = {6:1, 2:1}
const obj_6_3 = {6:1, 3:1}
const obj_6_4 = {6:1, 4:1}
const obj_6_5 = {6:1, 5:1}

const obj_7_1 = {7:1, 1:1}
const obj_7_2 = {7:1, 2:1}
const obj_7_3 = {7:1, 3:1}
const obj_7_4 = {7:1, 4:1}
const obj_7_5 = {7:1, 5:1}
const obj_7_6 = {7:1, 6:1}

const obj_8_1 = {8:1, 1:1}
const obj_8_2 = {8:1, 2:1}
const obj_8_3 = {8:1, 3:1}
const obj_8_4 = {8:1, 4:1}
const obj_8_5 = {8:1, 5:1}
const obj_8_6 = {8:1, 6:1}
const obj_8_7 = {8:1, 7:1}

const obj_9_1 = {9:1, 1:1}
const obj_9_2 = {9:1, 2:1}
const obj_9_3 = {9:1, 3:1}
const obj_9_4 = {9:1, 4:1}
const obj_9_5 = {9:1, 5:1}
const obj_9_6 = {9:1, 6:1}
const obj_9_7 = {9:1, 7:1}
const obj_9_8 = {9:1, 8:1}


// should error
safe_merge(obj_1, obj_2_1)
safe_merge(obj_1, obj_2_1b)

safe_merge(obj_1, obj_2, obj_3_1)
safe_merge(obj_1, obj_2, obj_3_2)

safe_merge(obj_1, obj_2, obj_3, obj_4_1)
safe_merge(obj_1, obj_2, obj_3, obj_4_2)
safe_merge(obj_1, obj_2, obj_3, obj_4_3)

safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5_4)

safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6_5)

safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7_6)

safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8_7)

safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_1)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_2)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_3)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_4)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_5)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_6)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_7)
safe_merge(obj_1, obj_2, obj_3, obj_4, obj_5, obj_6, obj_7, obj_8, obj_9_8)


0 commentaires