@@ -742,6 +742,9 @@ inline bool Value::IsExternal() const {
742742
743743template <typename T>
744744inline T Value::As () const {
745+ #ifdef NODE_ADDON_API_ENABLE_TYPE_CHECK_ON_AS
746+ T::CheckCast (_env, _value);
747+ #endif
745748 return T (_env, _value);
746749}
747750
@@ -784,6 +787,16 @@ inline Boolean Boolean::New(napi_env env, bool val) {
784787 return Boolean (env, value);
785788}
786789
790+ inline void Boolean::CheckCast (napi_env env, napi_value value) {
791+ NAPI_CHECK (value != nullptr , " Boolean::CheckCast" , " empty value" );
792+
793+ napi_valuetype type;
794+ napi_status status = napi_typeof (env, value, &type);
795+ NAPI_CHECK (status == napi_ok, " Boolean::CheckCast" , " napi_typeof failed" );
796+ NAPI_CHECK (
797+ type == napi_boolean, " Boolean::CheckCast" , " value is not napi_boolean" );
798+ }
799+
787800inline Boolean::Boolean () : Napi::Value() {}
788801
789802inline Boolean::Boolean (napi_env env, napi_value value)
@@ -811,6 +824,16 @@ inline Number Number::New(napi_env env, double val) {
811824 return Number (env, value);
812825}
813826
827+ inline void Number::CheckCast (napi_env env, napi_value value) {
828+ NAPI_CHECK (value != nullptr , " Number::CheckCast" , " empty value" );
829+
830+ napi_valuetype type;
831+ napi_status status = napi_typeof (env, value, &type);
832+ NAPI_CHECK (status == napi_ok, " Number::CheckCast" , " napi_typeof failed" );
833+ NAPI_CHECK (
834+ type == napi_number, " Number::CheckCast" , " value is not napi_number" );
835+ }
836+
814837inline Number::Number () : Value() {}
815838
816839inline Number::Number (napi_env env, napi_value value) : Value(env, value) {}
@@ -897,6 +920,16 @@ inline BigInt BigInt::New(napi_env env,
897920 return BigInt (env, value);
898921}
899922
923+ inline void BigInt::CheckCast (napi_env env, napi_value value) {
924+ NAPI_CHECK (value != nullptr , " BigInt::CheckCast" , " empty value" );
925+
926+ napi_valuetype type;
927+ napi_status status = napi_typeof (env, value, &type);
928+ NAPI_CHECK (status == napi_ok, " BigInt::CheckCast" , " napi_typeof failed" );
929+ NAPI_CHECK (
930+ type == napi_bigint, " BigInt::CheckCast" , " value is not napi_bigint" );
931+ }
932+
900933inline BigInt::BigInt () : Value() {}
901934
902935inline BigInt::BigInt (napi_env env, napi_value value) : Value(env, value) {}
@@ -946,6 +979,15 @@ inline Date Date::New(napi_env env, double val) {
946979 return Date (env, value);
947980}
948981
982+ inline void Date::CheckCast (napi_env env, napi_value value) {
983+ NAPI_CHECK (value != nullptr , " Date::CheckCast" , " empty value" );
984+
985+ bool result;
986+ napi_status status = napi_is_date (env, value, &result);
987+ NAPI_CHECK (status == napi_ok, " Date::CheckCast" , " napi_is_date failed" );
988+ NAPI_CHECK (result, " Date::CheckCast" , " value is not date" );
989+ }
990+
949991inline Date::Date () : Value() {}
950992
951993inline Date::Date (napi_env env, napi_value value) : Value(env, value) {}
@@ -965,6 +1007,16 @@ inline double Date::ValueOf() const {
9651007// //////////////////////////////////////////////////////////////////////////////
9661008// Name class
9671009// //////////////////////////////////////////////////////////////////////////////
1010+ inline void Name::CheckCast (napi_env env, napi_value value) {
1011+ NAPI_CHECK (value != nullptr , " Name::CheckCast" , " empty value" );
1012+
1013+ napi_valuetype type;
1014+ napi_status status = napi_typeof (env, value, &type);
1015+ NAPI_CHECK (status == napi_ok, " Name::CheckCast" , " napi_typeof failed" );
1016+ NAPI_CHECK (type == napi_string || type == napi_symbol,
1017+ " Name::CheckCast" ,
1018+ " value is not napi_string or napi_symbol" );
1019+ }
9681020
9691021inline Name::Name () : Value() {}
9701022
@@ -1024,6 +1076,16 @@ inline String String::New(napi_env env, const char16_t* val, size_t length) {
10241076 return String (env, value);
10251077}
10261078
1079+ inline void String::CheckCast (napi_env env, napi_value value) {
1080+ NAPI_CHECK (value != nullptr , " String::CheckCast" , " empty value" );
1081+
1082+ napi_valuetype type;
1083+ napi_status status = napi_typeof (env, value, &type);
1084+ NAPI_CHECK (status == napi_ok, " String::CheckCast" , " napi_typeof failed" );
1085+ NAPI_CHECK (
1086+ type == napi_string, " String::CheckCast" , " value is not napi_string" );
1087+ }
1088+
10271089inline String::String () : Name() {}
10281090
10291091inline String::String (napi_env env, napi_value value) : Name(env, value) {}
@@ -1151,6 +1213,16 @@ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, napi_value description) {
11511213#endif
11521214}
11531215
1216+ inline void Symbol::CheckCast (napi_env env, napi_value value) {
1217+ NAPI_CHECK (value != nullptr , " Symbol::CheckCast" , " empty value" );
1218+
1219+ napi_valuetype type;
1220+ napi_status status = napi_typeof (env, value, &type);
1221+ NAPI_CHECK (status == napi_ok, " Symbol::CheckCast" , " napi_typeof failed" );
1222+ NAPI_CHECK (
1223+ type == napi_symbol, " Symbol::CheckCast" , " value is not napi_symbol" );
1224+ }
1225+
11541226inline Symbol::Symbol () : Name() {}
11551227
11561228inline Symbol::Symbol (napi_env env, napi_value value) : Name(env, value) {}
@@ -1313,6 +1385,16 @@ inline Object Object::New(napi_env env) {
13131385 return Object (env, value);
13141386}
13151387
1388+ inline void Object::CheckCast (napi_env env, napi_value value) {
1389+ NAPI_CHECK (value != nullptr , " Object::CheckCast" , " empty value" );
1390+
1391+ napi_valuetype type;
1392+ napi_status status = napi_typeof (env, value, &type);
1393+ NAPI_CHECK (status == napi_ok, " Object::CheckCast" , " napi_typeof failed" );
1394+ NAPI_CHECK (
1395+ type == napi_object, " Object::CheckCast" , " value is not napi_object" );
1396+ }
1397+
13161398inline Object::Object () : TypeTaggable() {}
13171399
13181400inline Object::Object (napi_env env, napi_value value)
@@ -1719,6 +1801,18 @@ inline External<T> External<T>::New(napi_env env,
17191801 return External (env, value);
17201802}
17211803
1804+ template <typename T>
1805+ inline void External<T>::CheckCast(napi_env env, napi_value value) {
1806+ NAPI_CHECK (value != nullptr , " External::CheckCast" , " empty value" );
1807+
1808+ napi_valuetype type;
1809+ napi_status status = napi_typeof (env, value, &type);
1810+ NAPI_CHECK (status == napi_ok, " External::CheckCast" , " napi_typeof failed" );
1811+ NAPI_CHECK (type == napi_external,
1812+ " External::CheckCast" ,
1813+ " value is not napi_external" );
1814+ }
1815+
17221816template <typename T>
17231817inline External<T>::External() : TypeTaggable() {}
17241818
@@ -1752,6 +1846,15 @@ inline Array Array::New(napi_env env, size_t length) {
17521846 return Array (env, value);
17531847}
17541848
1849+ inline void Array::CheckCast (napi_env env, napi_value value) {
1850+ NAPI_CHECK (value != nullptr , " Array::CheckCast" , " empty value" );
1851+
1852+ bool result;
1853+ napi_status status = napi_is_array (env, value, &result);
1854+ NAPI_CHECK (status == napi_ok, " Array::CheckCast" , " napi_is_array failed" );
1855+ NAPI_CHECK (result, " Array::CheckCast" , " value is not array" );
1856+ }
1857+
17551858inline Array::Array () : Object() {}
17561859
17571860inline Array::Array (napi_env env, napi_value value) : Object(env, value) {}
@@ -1838,6 +1941,17 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
18381941}
18391942#endif // NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
18401943
1944+ inline void ArrayBuffer::CheckCast (napi_env env, napi_value value) {
1945+ NAPI_CHECK (value != nullptr , " ArrayBuffer::CheckCast" , " empty value" );
1946+
1947+ bool result;
1948+ napi_status status = napi_is_arraybuffer (env, value, &result);
1949+ NAPI_CHECK (status == napi_ok,
1950+ " ArrayBuffer::CheckCast" ,
1951+ " napi_is_arraybuffer failed" );
1952+ NAPI_CHECK (result, " ArrayBuffer::CheckCast" , " value is not arraybuffer" );
1953+ }
1954+
18411955inline ArrayBuffer::ArrayBuffer () : Object() {}
18421956
18431957inline ArrayBuffer::ArrayBuffer (napi_env env, napi_value value)
@@ -1905,6 +2019,16 @@ inline DataView DataView::New(napi_env env,
19052019 return DataView (env, value);
19062020}
19072021
2022+ inline void DataView::CheckCast (napi_env env, napi_value value) {
2023+ NAPI_CHECK (value != nullptr , " DataView::CheckCast" , " empty value" );
2024+
2025+ bool result;
2026+ napi_status status = napi_is_dataview (env, value, &result);
2027+ NAPI_CHECK (
2028+ status == napi_ok, " DataView::CheckCast" , " napi_is_dataview failed" );
2029+ NAPI_CHECK (result, " DataView::CheckCast" , " value is not dataview" );
2030+ }
2031+
19082032inline DataView::DataView () : Object() {}
19092033
19102034inline DataView::DataView (napi_env env, napi_value value) : Object(env, value) {
@@ -2039,6 +2163,15 @@ inline void DataView::WriteData(size_t byteOffset, T value) const {
20392163// //////////////////////////////////////////////////////////////////////////////
20402164// TypedArray class
20412165// //////////////////////////////////////////////////////////////////////////////
2166+ inline void TypedArray::CheckCast (napi_env env, napi_value value) {
2167+ NAPI_CHECK (value != nullptr , " TypedArray::CheckCast" , " empty value" );
2168+
2169+ bool result;
2170+ napi_status status = napi_is_typedarray (env, value, &result);
2171+ NAPI_CHECK (
2172+ status == napi_ok, " TypedArray::CheckCast" , " napi_is_typedarray failed" );
2173+ NAPI_CHECK (result, " TypedArray::CheckCast" , " value is not typedarray" );
2174+ }
20422175
20432176inline TypedArray::TypedArray ()
20442177 : Object(), _type(napi_typedarray_type::napi_int8_array), _length(0 ) {}
@@ -2121,6 +2254,23 @@ inline Napi::ArrayBuffer TypedArray::ArrayBuffer() const {
21212254// //////////////////////////////////////////////////////////////////////////////
21222255// TypedArrayOf<T> class
21232256// //////////////////////////////////////////////////////////////////////////////
2257+ template <typename T>
2258+ inline void TypedArrayOf<T>::CheckCast(napi_env env, napi_value value) {
2259+ TypedArray::CheckCast (env, value);
2260+ napi_typedarray_type type;
2261+ napi_status status = napi_get_typedarray_info (
2262+ env, value, &type, nullptr , nullptr , nullptr , nullptr );
2263+ NAPI_CHECK (status == napi_ok,
2264+ " TypedArrayOf::CheckCast" ,
2265+ " napi_is_typedarray failed" );
2266+
2267+ NAPI_CHECK (
2268+ (type == TypedArrayTypeForPrimitiveType<T>() ||
2269+ (type == napi_uint8_clamped_array && std::is_same<T, uint8_t >::value)),
2270+ " TypedArrayOf::CheckCast" ,
2271+ " Array type must match the template parameter. (Uint8 arrays may "
2272+ " optionally have the \" clamped\" array type.)" );
2273+ }
21242274
21252275template <typename T>
21262276inline TypedArrayOf<T> TypedArrayOf<T>::New(napi_env env,
@@ -2294,6 +2444,17 @@ inline Function Function::New(napi_env env,
22942444 return New (env, cb, utf8name.c_str (), data);
22952445}
22962446
2447+ inline void Function::CheckCast (napi_env env, napi_value value) {
2448+ NAPI_CHECK (value != nullptr , " Function::CheckCast" , " empty value" );
2449+
2450+ napi_valuetype type;
2451+ napi_status status = napi_typeof (env, value, &type);
2452+ NAPI_CHECK (status == napi_ok, " Function::CheckCast" , " napi_typeof failed" );
2453+ NAPI_CHECK (type == napi_function,
2454+ " Function::CheckCast" ,
2455+ " value is not napi_function" );
2456+ }
2457+
22972458inline Function::Function () : Object() {}
22982459
22992460inline Function::Function (napi_env env, napi_value value)
@@ -2440,6 +2601,15 @@ inline void Promise::Deferred::Reject(napi_value value) const {
24402601 NAPI_THROW_IF_FAILED_VOID (_env, status);
24412602}
24422603
2604+ inline void Promise::CheckCast (napi_env env, napi_value value) {
2605+ NAPI_CHECK (value != nullptr , " Promise::CheckCast" , " empty value" );
2606+
2607+ bool result;
2608+ napi_status status = napi_is_promise (env, value, &result);
2609+ NAPI_CHECK (status == napi_ok, " Promise::CheckCast" , " napi_is_promise failed" );
2610+ NAPI_CHECK (result, " Promise::CheckCast" , " value is not promise" );
2611+ }
2612+
24432613inline Promise::Promise (napi_env env, napi_value value) : Object(env, value) {}
24442614
24452615// //////////////////////////////////////////////////////////////////////////////
@@ -2612,6 +2782,16 @@ inline Buffer<T> Buffer<T>::Copy(napi_env env, const T* data, size_t length) {
26122782 return Buffer<T>(env, value);
26132783}
26142784
2785+ template <typename T>
2786+ inline void Buffer<T>::CheckCast (napi_env env, napi_value value) {
2787+ NAPI_CHECK (value != nullptr , " Buffer::CheckCast" , " empty value" );
2788+
2789+ bool result;
2790+ napi_status status = napi_is_buffer (env, value, &result);
2791+ NAPI_CHECK (status == napi_ok, " Buffer::CheckCast" , " napi_is_buffer failed" );
2792+ NAPI_CHECK (result, " Buffer::CheckCast" , " value is not buffer" );
2793+ }
2794+
26152795template <typename T>
26162796inline Buffer<T>::Buffer () : Uint8Array (), _length (0 ), _data (nullptr ) {}
26172797
0 commit comments