implemented a proposal for #278
diff --git a/src/json.hpp b/src/json.hpp
index 878fb89..3ad68d0 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -3854,6 +3854,37 @@
         return value(ptr, string_t(default_value));
     }
 
+    template <class ValueType, typename
+              std::enable_if<
+                  std::is_convertible<basic_json_t, ValueType>::value
+                  , int>::type = 0>
+    ValueType value_with_type(const typename object_t::key_type& key,
+                              ValueType default_value) const
+    {
+        // derive JSON value type from given default value
+        const value_t return_value_type = basic_json(default_value).type();
+
+        // at only works for objects
+        if (is_object())
+        {
+            // if key is found and stored value has the same type as the
+            // default value, return value and given default value otherwise
+            const auto it = find(key);
+            if (it != end() and it->type() == return_value_type)
+            {
+                return *it;
+            }
+            else
+            {
+                return default_value;
+            }
+        }
+        else
+        {
+            throw std::domain_error("cannot use value() with " + type_name());
+        }
+    }
+
     /*!
     @brief access the first element
 
diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c
index 32482ea..367c0ee 100644
--- a/src/json.hpp.re2c
+++ b/src/json.hpp.re2c
@@ -3854,6 +3854,37 @@
         return value(ptr, string_t(default_value));
     }
 
+    template <class ValueType, typename
+              std::enable_if<
+                  std::is_convertible<basic_json_t, ValueType>::value
+                  , int>::type = 0>
+    ValueType value_with_type(const typename object_t::key_type& key,
+                              ValueType default_value) const
+    {
+        // derive JSON value type from given default value
+        const value_t return_value_type = basic_json(default_value).type();
+
+        // at only works for objects
+        if (is_object())
+        {
+            // if key is found and stored value has the same type as the
+            // default value, return value and given default value otherwise
+            const auto it = find(key);
+            if (it != end() and it->type() == return_value_type)
+            {
+                return *it;
+            }
+            else
+            {
+                return default_value;
+            }
+        }
+        else
+        {
+            throw std::domain_error("cannot use value() with " + type_name());
+        }
+    }
+
     /*!
     @brief access the first element
 
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index 79a4bb0..27aff7f 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -14373,6 +14373,30 @@
 
         CHECK(at_integer == val_integer);
     }
+
+    SECTION("issue #278 - Do not throw exception when default_value's type does not match the actual type")
+    {
+        json j =
+        {
+            {"port", 1234}, {"proxy", true}
+        };
+
+        int port1 = j.value_with_type("port", 8080);
+        int port2 = j.value_with_type("the_port", 8080);
+        int port3 = j.value_with_type("proxy", 8080);
+
+        bool proxy1 = j.value_with_type("proxy", false);
+        bool proxy2 = j.value_with_type("the_proxy", false);
+        bool proxy3 = j.value_with_type("port", false);
+
+        CHECK(port1 == 1234);
+        CHECK(port2 == 8080);
+        CHECK(port3 == 8080);
+
+        CHECK(proxy1 == true);
+        CHECK(proxy2 == false);
+        CHECK(proxy3 == false);
+    }
 }
 
 // special test case to check if memory is leaked if constructor throws