diff --git a/json-spec.cabal b/json-spec.cabal
--- a/json-spec.cabal
+++ b/json-spec.cabal
@@ -1,6 +1,6 @@
 cabal-version:       3.0
 name:                json-spec
-version:             0.4.1.0
+version:             0.5.0.0
 synopsis:            Type-level JSON specification
 maintainer:          rick@owensmurray.com
 description:         See the README at: https://github.com/owensmurray/json-spec#json-spec
diff --git a/src/Data/JsonSpec.hs b/src/Data/JsonSpec.hs
--- a/src/Data/JsonSpec.hs
+++ b/src/Data/JsonSpec.hs
@@ -74,6 +74,7 @@
   SpecJSON(..),
   Tag(..),
   Field(..),
+  unField,
   JSONStructure,
   Rec(..),
   eitherDecode,
@@ -90,11 +91,11 @@
   fromJSONStructure), StructureFromJSON(reprParseJSON), eitherDecode)
 import Data.JsonSpec.Encode (HasJsonEncodingSpec(EncodingSpec,
   toJSONStructure), StructureToJSON(reprToJSON), encode)
-import Data.JsonSpec.Spec (Field(Field, unField), FieldSpec(Optional,
-  Required), Rec(Rec, unRec), Specification(JsonArray, JsonBool,
-  JsonDateTime, JsonEither, JsonInt, JsonLet, JsonNullable, JsonNum,
-  JsonObject, JsonRaw, JsonRef, JsonString, JsonTag), Tag(Tag), (:::),
-  (::?), JSONStructure)
+import Data.JsonSpec.Spec (Field(Field), FieldSpec(Optional, Required),
+  Rec(Rec, unRec), Specification(JsonArray, JsonBool, JsonDateTime,
+  JsonEither, JsonInt, JsonLet, JsonNullable, JsonNum, JsonObject,
+  JsonRaw, JsonRef, JsonString, JsonTag), Tag(Tag), (:::), (::?),
+  JSONStructure, unField)
 import Prelude ((.), (<$>), (=<<))
 
 
diff --git a/src/Data/JsonSpec/Spec.hs b/src/Data/JsonSpec/Spec.hs
--- a/src/Data/JsonSpec/Spec.hs
+++ b/src/Data/JsonSpec/Spec.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE PolyKinds #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 {-# LANGUAGE TypeFamilies #-}
@@ -13,6 +14,7 @@
   sym,
   Tag(..),
   Field(..),
+  unField,
   Rec(..),
   JStruct,
   FieldSpec(..),
@@ -28,7 +30,9 @@
 import Data.String (IsString(fromString))
 import Data.Text (Text)
 import Data.Time (UTCTime)
+import GHC.Records (HasField(getField))
 import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
+import Prelude (($), Bool, Either, Eq, Int, Maybe, Show)
 
 
 {-|
@@ -201,6 +205,12 @@
   > (Field @key3 valueType,
   > ())))
 
+  Note! "Object structures" of this type have the appropriate 'HasField'
+  instances, which allows you to use -XOverloadedRecordDot to extract
+  values as an alternative to pattern matching the whole tuple structure
+  when building your 'HasJsonDecodingSpec' instances. See @TestHasField@
+  in the tests for an example
+
   Arrays, booleans, numbers, and strings are just Lists, 'Bool's,
   'Scientific's, and 'Text's respectively.
 
@@ -323,8 +333,16 @@
 
 
 {-| Structural representation of an object field. -}
-newtype Field (key :: Symbol) t = Field {unField :: t}
+newtype Field (key :: Symbol) t = Field t
   deriving stock (Show, Eq)
+instance {-# overlappable #-} (HasField k more v) => HasField k (Field notIt x, more) v where
+  getField (_, more) = getField @k @_ @v more
+instance HasField k (Field k v, more) v where
+  getField (Field v, _) = v
+
+
+unField :: Field key t -> t
+unField (Field t) = t
 
 
 {- |
diff --git a/test/jsonspec.hs b/test/jsonspec.hs
--- a/test/jsonspec.hs
+++ b/test/jsonspec.hs
@@ -2,6 +2,7 @@
 {-# LANGUAGE DerivingVia #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE OverloadedRecordDot #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
@@ -11,6 +12,7 @@
 {-# LANGUAGE ViewPatterns #-}
 
 {-# OPTIONS_GHC -Wwarn #-} {- Because of GHC-69797 -}
+{- But re-enable the errors we most care about -}
 {-# OPTIONS_GHC -Werror=missing-import-lists #-}
 
 module Main (main) where
@@ -18,21 +20,22 @@
 import Control.Monad (join)
 import Data.Aeson (FromJSON, ToJSON)
 import Data.ByteString.Lazy (ByteString)
-import Data.JsonSpec (Field(Field, unField), FieldSpec(Optional,
+import Data.JsonSpec (Field(Field), FieldSpec(Optional,
   Required), HasJsonDecodingSpec(DecodingSpec, fromJSONStructure),
   HasJsonEncodingSpec(EncodingSpec, toJSONStructure), Rec(Rec, unRec),
   SpecJSON(SpecJSON), Specification(JsonArray, JsonBool, JsonDateTime,
   JsonEither, JsonInt, JsonLet, JsonNullable, JsonNum, JsonObject,
   JsonRaw, JsonRef, JsonString, JsonTag), Tag(Tag), (:::), (::?),
-  eitherDecode, encode)
+  eitherDecode, encode, unField)
 import Data.Proxy (Proxy(Proxy))
 import Data.Scientific (Scientific)
 import Data.Text (Text)
 import Data.Time (UTCTime(UTCTime))
 import OM.Show (ShowJ(ShowJ))
-import Prelude (Applicative(pure), Bool(False, True), Either(Left,
-  Right), Enum(toEnum), Functor(fmap), Maybe(Just, Nothing), Monad((>>=)),
-  Traversable(traverse), ($), (.), Eq, IO, Int, Show, String, realToFrac)
+import Prelude (Applicative(pure), Bool(False, True), Either(Left, Right),
+  Enum(toEnum), Functor(fmap), Maybe(Just, Nothing), Monad((>>=)),
+  Num(negate), Traversable(traverse), ($), (.), Eq, IO, Int, Show,
+  String, realToFrac)
 import Test.Hspec (describe, hspec, it, shouldBe)
 import qualified Data.Aeson as A
 
@@ -399,7 +402,36 @@
           in
             actual `shouldBe` expected
 
+      it "HasField" $
+        let
+          expected :: Maybe TestHasField
+          expected =
+            Just
+              TestHasField
+                { thfFoo = "foo"
+                , thfBar = 10
+                , thfBaz =
+                    TestSubObj
+                      { foo2 = "bar"
+                      , bar2 = negate 10
+                      }
+                }
 
+          actual :: Maybe TestHasField
+          actual =
+            A.decode
+              "{\
+              \  \"foo\": \"foo\",\
+              \  \"bar\": 10,\
+              \  \"baz\": {\
+              \    \"a_string\": \"bar\",\
+              \    \"an_int\": -10\
+              \  }\
+              \}"
+        in
+          actual `shouldBe` expected
+
+
 sampleTestObject :: TestObj
 sampleTestObject =
   TestObj
@@ -709,5 +741,36 @@
       ()))))
     =
       pure TestOptionality { toFoo , toBar , toBaz , toQux }
+
+
+data TestHasField = TestHasField
+  { thfFoo :: Text
+  , thfBar :: Int
+  , thfBaz :: TestSubObj
+  }
+  deriving stock (Show, Eq)
+  deriving (FromJSON) via (SpecJSON TestHasField)
+instance HasJsonDecodingSpec TestHasField where
+  type DecodingSpec TestHasField =
+    JsonObject
+      '[ "foo" ::: JsonString
+       , "bar" ::: JsonInt
+       , "baz" ::: JsonObject
+                    '[ "a_string" ::: JsonString
+                     ,   "an_int" ::: JsonInt
+                     ]
+       ]
+  fromJSONStructure val =
+    pure
+      TestHasField
+        { thfFoo = val.foo
+        , thfBar = val.bar
+        , thfBaz =
+            TestSubObj
+              { foo2 = val.baz.a_string
+              , bar2 = val.baz.an_int
+              }
+
+        }
 
 
