Arrays are objects, so this is expected behaviour.
Arrays are objects, so this is expected behaviour.
[0]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Object.getOwnPropertyDescriptors(Array.isArray)
/*
{
'0': {
value: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray',
writable: true,
enumerable: true,
configurable: true
},
length: { value: 1, writable: false, enumerable: false, configurable: true },
name: {
value: 'isArray',
writable: false,
enumerable: false,
configurable: true
}
}
*/ Array.isArray[0] = urlString function isHuman(input: any): input is Human {
return (
Boolean(input) &&
Object.prototype.hasOwnProperty.call(input, "name") &&
Object.prototype.hasOwnProperty.call(input, "age")
);
}
There are libraries which can automate this for you which is the route I would recommend if you need to do this often. As you can see, the code to cover all edge cases such as `Object.create(null)` etc is not trivial.[0] https://www.typescriptlang.org/docs/handbook/advanced-types....
"What is object? I don't know. Does it meet these conditions? Yes then object is Human else not."
All this boilerplate is not a proof. It remains an assertion. And so in most cases you might as well just add a "type"/"kind" property to your object (or create a class).
Which libraries do you recommend? I've had to do this a couple of times in my current project and it's painful (and I made mistakes).
[0] https://github.com/arcanis/typanion
You don't need a library or check that it isn't an array or anything like that. What you actually want to check is what it _is_.
You absolutely don't care whether that object is an array or a function or what have you. What you care about in that piece of code is that it satisfies what you want to do with it.
In the context of the article you can do an ad-hoc check on the fields that you require in that context.
Aside:
There are places where you want to have a kind of rigidity around the shape of your objects, including homogeneous collections. The JIT might reward you with optimizations in certain cases. But that is optimization, so you are supposed to measure first and only then apply them or have a very clear picture of how your runtime behavior will be.
https://github.com/lodash/lodash/blob/master/isObject.js
But depends on your needs, and you can also attach a typeguard to it.
You'll also get notified of any security issues in your lodash imports if your CI pipeline is setup for doing that kind of thing.
its typical to start off with `var &&` to avoid operations on null & undefined values
!!(x && x.__proto__ === [].__proto__)
> if(entry && entry.constructor === Object){}
entry = Object.create(null);
entry.name = "Jason";
entry.age = 42;
entry.constructor === Object // false - constructor is undefined.
`entry` is a valid Human here, but fails your check. Actually, just creating a new class that implements the Human interface will cause a similar problem, since the constructor will be the class instead of Object. You don't even really want to exclude arrays here: entry = []
entry['name'] = "Jason";
entry['age'] = 42;
Again, entry is a valid Human here. function isHuman(obj: unknown): obj is Human {
return !!obj &&
typeof obj === 'object' &&
typeof (obj as any).name === 'string' &&
typeof (obj as any).age === 'number';
}
This checks the shape of the object, and returns true if it's a `Human`. This will work for array or objects or classes or anything.tl;dr: Object.prototype.toString.call, you most likely to also want to exclude null, RegExp, Function, Date, Number, Boolean & String (not string)
any => Object.prototype.toString.call(any).slice(8, -1)
typeName = Object.prototype.toString.call