I am a beginner to JS. I know some basic things about JS like: if..else, and checking if a value is number, or string.
I want to create a function which receives the object as its only argument and return an object with the same properties, but with type validation added.
What I mean is something similar to this:
const obj = {
age_int: 2,
name_string: "Adam",
job: null,
}
const validatingObject = typeCheck(obj)
validatingObject.age_int = 2.25 // Throws error
validatingObject.age_int = 2
validatingObject.job = "fireman"
validatingObject.address_string = 20 // Throws error
const obj_2 = {
employed_bool: "true",
}
const validatingObject = typeCheck(obj_2) // Throws error
Now, The type validation is always be based on the last part of the property name. For example, the age_int is for int
.
Possible:
- string: for example,
"string type"
- int:
12.00
and12
are both integers - float: for example,
12.34
- number: any int or float
- bool: for example,
true
As I did not know about working with Objects, I was not able to do anything in this. I need help in proceeding.
CodePudding user response:
This is not a kind of code I'd expect to see in real world projects, but it's perfectly fine to do experiments like this for the purpose of learning. If you do have such a requirement, you'll need to set some rules and boundaries before starting to write the code.
For example:
- If the input object is going to hold the expected type in the names of its keys, then make sure that each property of the said object has the type. From your code,
age_int
is proper input, butjob
is not. - Learn about the types that the language of your choice offers. You want
int
andfloat
, but JavaScript does not have them - onlynumber
. You can of course make a custom function that spits out the type you're looking for, but you need to know the native types in the first place. - Be clear in what you want your program to do. You want
int
andfloat
separately, and you also wantnumber
reported as is. I'm not saying it's not at all possible to do both, but it's bad design, introduces unnecessary complexity into your code, and affects the performance as well if done at scale. - Consider not throwing errors based on conditional checks that don't warrant an exception/fatal situation. You can return booleans, string messages or any suitable values and handle the outcome accordingly.
All that said, here's a possible solution for what you're looking for:
const getType = (value) => {
if (typeof value == "string") return "string";
if (typeof value == "boolean") return "boolean";
if (typeof value == "number") {
return value % parseInt(value) == 0 ? "int" : "float";
}
return "unknown";
}
const typeCheck = (obj) => {
// let copiedObj = {...obj}; Editing this out, since I didn't do anything with it, which I intended for returning originally.
for (let key in Object.keys(obj)) {
const givenType = key.split("_")[1];
if (givenType !== getType(obj[key])) {
return false;
}
}
return true;
}
const obj = {
age_int: 2,
name_string: "Adam",
job: null, // This should fail since key.split("_")[1] above would return undefined
}
let validatingObject = typeCheck(obj)
console.log(validatingObject);
const obj_2 = {
employed_bool: "true", // Should fail
}
validatingObject = typeCheck(obj_2)
console.log(validatingObject);
CodePudding user response:
You can use the following ways for validating the type of Object in Javascript:
Using the instanceof
operator
The instanceof
operator can be used as following:
var myArray = [1,2,3];
(myArray instanceof Array); // true
(Array.isArray(myArray)); // true (Preferred approach for arrays)
(myArray instanceof Object); // true
Note:
When checking for an Array instance, Array.isArray()
is preferred over instanceof
because it works across realms.
Using the typeof
operator
Per the MDN docmentation, typeof
is a unary operator that returns a string indicating the type of the unevaluated operand.
In the case of string primitives and string objects, typeof
returns the following:
const a = "I'm a string primitive";
const b = new String("I'm a String Object");
typeof a; --> returns 'string'
typeof b; --> returns 'object'
Note: A good reason to use typeof
is if the variable may be undefined. A good reason to use instanceof
is if the variable may be null.
Also, instanceof
cannot compare to primitive types, typeof
can.
Using Object.prototype.toString
property
Also, you can use Object.prototype.toString
- the low-level and generic implementation of toString - to get the type for all built-in types
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
One could write a short helper function such as
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
to remove the cruft and get at just the type name
type('abc') // String
However, it will return Object
for all user-defined types.