DEV Community

Discussion on: Better TypeScript... With JavaScript

Collapse
 
functional_js profile image
Functional Javascript • Edited

Nice work Adam.

It's eerily similar to my runtime check library. :)

Well maybe not so eerie, because these types of checks just makes sense for validating input.

What's different is that I take a functional approach; so no classes, no methods, no optional params, no this-keyword, no method chaining.

I also have a separate set of funcs in another module specifically for throwing. My typechecker module itself only contains checker funcs that only return bools.

The chaining is a cool idea, but I couldn't use it with oneliner funcs smoothly.

Here's an example usage using the isNotNil checker func...

/**
@func
is the arg an instance of an obj?
- i.e. a {} type and no other javascript typeof "object" object

@notes
an empty obj is also true

@cons
may not work in IE 11

@param {{}} o obj expected
@return {boolean}
*/
export const isObj = o => isNotNil(o) && o.constructor === Object;

Here's another example usage using a "throwIf" func from my throwIf module...

/**
@func
sleep the amount of milliseconds supplied by the arg

@usages
await sleeper(2000);

@cons
must use await, otherwise it won't sleep

@param {number} ms delay in milliseconds
@return {Promise<void>}
*/
export const sleeper = ms => throwIfNumLessThanZero(ms) || new Promise(resolve => setTimeout(resolve, ms));

P.S.

I'll mention also that taking a functional approach using free funcs—each with their own "exports"—allows one to take advantage of tree-shaking. It's usually not common for a module to use more than one or two of the checker or throwIf funcs.

Collapse
 
bytebodger profile image
Adam Nathaniel Davis

What's different is that I take a functional approach;

Very shocking, coming from the guy whose username is Functional Javascript :-)

Seriously, though. I rarely use classes for much of anything anymore. I do find them to be practical and useful when creating little libraries of utility functions - which is what this is. Especially when some of those functions need to call each other. But you could definitely do this without the class.

no optional params

I only just recently added them in my latest iteration. I've been using a previous homegrown library for several years with no params. However, one of the biggest things that I like to check for is making sure that the data types aren't empty. Cuz if you're expecting a string/object/array, it's quite common that an empty string/object/array isn't valid.

To get around this before, I'd have functions like aString() and .aPopulatedString(). Adding the optional param was just a way for me to collapse those into a single validation.

no method chaining

That was also something that was only added just recently. I don't think I'd ever written something designed for chaining, but one of my coworkers suggested it because I often have a function with two-or-three arguments. And I want to provide validation on each one. So the chaining is just a way to conveniently and logically collapse into into a single LoC - in the same way that the function signature itself is usually a single LoC.

Here's another example usage using a "throwIf" func from my throwIf module...

It's definitely interesting to see your approach. Great minds, and all that...

I especially like how you've logically concatenate them in front of the eventual function call.

Thanks for the feedback!