6 ms·
Note: don't use typeof x === 'object' to check whether something is a valid object, because it will return true for arrays as well. Arrays are objects, so this
by EnderShadow8 5y ago
Note: don't use typeof x === 'object' to check whether something is a valid object, because it will return true for arrays as well.
Arrays are objects, so this is expected behaviour.
- threatofrain 5y agoHow about any => Object.prototype.toString.call(any).slice(8, -1)
- nsonha 5y agoor even this typeName = Object.prototype.toString.call
- JoBrad 5y agoI really like this package, because it not only uses the method you mentioned for checking types, but is written in TS, so you get the type checking feedback. https://github.com/sindresorhus/is https://github.com/sindresorhus/is
- deleted 5y ago[deleted]
- nsonha 5y agobit more self-explanatory `it => Object.prototype.toString.call(it).match(/^\[object (\w+)]/).pop()`
- conaclos 5y agoAnd it will return true for null as well ;)
- WA 5y agoNote: please post a better solution.
- nicoburns 5y agoIf you want to avoid a library then you can do `typeof x === "object" && !Array.isArray(x) && x !== null`. Not ideal, but you can of course turn it into a utility function.
- deleted 5y ago[deleted]
- presentation 5y agoProbably best to just lift one off of a major library like Lodash, they're well tested and efficient (no need to actually use the library, do include the LICENSE somewhere though): https://github.com/lodash/lodash/blob/master/isObject.js https://github.com/lodash/lodash/blob/master/isObject.js But depends on your needs, and you can also attach a typeguard to it.
- chucky 5y agoWhy not use the library? With tree shaking and/or direct imports you will ensure the same bundle size as if you just copied the file, and you don't have to worry about licenses etc. In fact, since other dependencies might depend on lodash you can deduplicate the import and actually save on bundle size. 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.
- presentation 5y agoMostly if you look at it out of the context of a single function - a lot of projects end up taking a huge number of dependencies, with a lot of overlapping functionality, because you used one function from this one, another function from that one… I’m fine with using libraries when they actually do heavy lifting that’s core to an application, but a single two line function requiring including hundreds of unrelated irrelevant ones? That will impact the coding style of your team and does have security downsides, like needing to trust the library authors and potentially breaking your build because they changed their APIs or deleted a package or whatever. Copying a 2 line function has very clear boundaries to what it can and can’t do, and doesn’t hide the internals of what you’re doing behind the mystique of “an external dependency”.
- cstrnt 5y agoYou're absolutely right. Should have stated that I meant a plain object (key-value-pair). But either didn't want to focus on this topic for that post because it would have been just a bit too much to talk about :D
- hardwaresofton 5y agoArray.isArray[0] is your friend [0]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- IggleSniggle 5y agoDid anybody else have their brain do a weird backflip seeing `Array.isArray[0]`?? 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 } } */
- panzerklein 5y agoHow did you get that result? I only see length and name.
- IggleSniggle 5y agoWell, it was a kind of a joke intended for the folks whose brain saw the comment the same way I did. I got the result by applying the footnote to the object, as half-suggested by syntax of the parent: Array.isArray[0] = urlString
- Etheryte 5y agoThe core problem here is that you don't actually want to check if something is an object, but whether it matches the Human type. The correct way to do that is to define a type guard [0], for example: 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.html#user-defined-type-guards https://www.typescriptlang.org/docs/handbook/advanced-types....
- wdfx 5y agoYour input parameter type should be unknown, not any.
- Etheryte 5y agoThat's fairly subjective and I can see arguments for both sides, in the above example I've gone with the approach the Typescript documentation itself gives which uses any. Given the parameter is only used as an input, using any and unknown are interchangeable and there is no difference in this specific case.
- wdfx 5y agoI somewhat agree, but to me the semantics using unknown makes more sense as the function is attempting to answer a question of the input object. "What is object? I don't know. Does it meet these conditions? Yes then object is Human else not."
- Etheryte 5y agoWhile I see where you're coming from, semantic formulation like this is highly subjective. All the same the problem statement could be "Given any kind of input, tell me whether it's a Human or not".