diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog for `type-machine`
 
+## 0.1.0.2 - 2025-09-02
+
+- Add `union`/`intersectionWithSelector`
+
 ## 0.1.0.1 - 2025-08-11
 
 - Expose 'Liftable' module
diff --git a/src/TypeMachine/Functions.hs b/src/TypeMachine/Functions.hs
--- a/src/TypeMachine/Functions.hs
+++ b/src/TypeMachine/Functions.hs
@@ -23,6 +23,11 @@
     apply,
     applyMany,
 
+    -- * With Selector
+    intersectionWithSelector,
+    unionWithSelector,
+    Selector,
+
     -- * Utils
     keysOf,
 )
@@ -41,6 +46,7 @@
 import TypeMachine.Log
 import TypeMachine.TM
 import TypeMachine.Type
+import Prelude hiding (Either (..))
 
 -- | Mark fields are required
 --
@@ -111,12 +117,7 @@
 --  data _ = { b :: Int }
 -- @
 intersection :: Type -> Type -> TM Type
-intersection a b = do
-    failIfHasTypeVariables a
-    failIfHasTypeVariables b
-    let finalType = a{fields = Map.intersection (fields a) (fields b)}
-    logIfEmptyType finalType
-    return finalType
+intersection = intersectionWithSelector (const Left)
 
 -- | Keep the fields present in both types
 --
@@ -130,9 +131,25 @@
 --  data _ = { b :: String }
 -- @
 intersection' :: Type -> Type -> TM Type
-intersection' = flip intersection
+intersection' = intersectionWithSelector (const Right)
 {-# INLINE intersection' #-}
 
+-- | Variant of 'intersection' where user can decide which value to keep (the left object's or the right's) in case of overlap
+intersectionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type
+intersectionWithSelector select a b = do
+    failIfHasTypeVariables a
+    failIfHasTypeVariables b
+    let finalType =
+            a
+                { fields =
+                    Map.intersectionWithKey
+                        (\key aField bField -> if select key == Left then aField else bField)
+                        (fields a)
+                        (fields b)
+                }
+    logIfEmptyType finalType
+    return finalType
+
 -- | Merge two types together
 --
 --  If keys overlap, prefer the type of the left type
@@ -145,10 +162,7 @@
 --  data _ = { a :: Int, b :: Int, c :: Void }
 -- @
 union :: Type -> Type -> TM Type
-union a b = do
-    failIfHasTypeVariables a
-    failIfHasTypeVariables b
-    return $ a{fields = Map.union (fields a) (fields b)}
+union = unionWithSelector (const Left)
 
 -- | Merge two types together
 --
@@ -162,9 +176,23 @@
 --  data _ = { a :: Int, b :: String, c :: Void }
 -- @
 union' :: Type -> Type -> TM Type
-union' = flip union
+union' = unionWithSelector (const Right)
 {-# INLINE union' #-}
 
+-- | Variant of 'union' where user can decide which value to keep (the left object's or the right's) in case of overlap
+unionWithSelector :: (String -> Selector) -> Type -> Type -> TM Type
+unionWithSelector select a b = do
+    failIfHasTypeVariables a
+    failIfHasTypeVariables b
+    return $
+        a
+            { fields =
+                Map.unionWithKey
+                    (\key aField bField -> if select key == Left then aField else bField)
+                    (fields a)
+                    (fields b)
+            }
+
 -- | Get the names of the fields in in type
 --
 -- @
@@ -273,6 +301,9 @@
 -- @
 applyMany :: [Q TH.Type] -> Type -> TM Type
 applyMany typeArgs ty = foldM (flip apply) ty typeArgs
+
+-- | Selector for functions like 'intersectionWithSelector'
+data Selector = Left | Right deriving (Eq, Show)
 
 -- Utils for logs
 
diff --git a/type-machine.cabal b/type-machine.cabal
--- a/type-machine.cabal
+++ b/type-machine.cabal
@@ -1,11 +1,11 @@
 cabal-version: 2.2
 
--- This file has been generated from package.yaml by hpack version 0.38.0.
+-- This file has been generated from package.yaml by hpack version 0.38.1.
 --
 -- see: https://github.com/sol/hpack
 
 name:           type-machine
-version:        0.1.0.1
+version:        0.1.0.2
 synopsis:       Type-level functions for record types
 category:       Types
 homepage:       https://github.com/Arthi-chaud/type-machine#readme
