🌌
extensions.macro Extension functions and parameters for JavaScript inspired by Kotlin's extensions
Installation
npm i extensions.macro
Or if using yarn:
yarn add extensions.macro
Then just import
:
import extension from 'extensions.macro'
Note that you need to have
babel
andbabel-plugin-macros
installed
Motivation
As you might know - providing new properties to JavaScript built-in objects pollutes the global scope and is widely considered unsafe. This macro solves the problem allowing you to use dot notation to access external functions and properties
Examples
Declaring extension
import extension from 'extensions.macro'
extension.String.plus = string => plusString => `${string} ${plusString}`
Note that it's initialized with function witch first argumument(
string
) provides an instance it's called on.
Then you can use it like:
'Hello'.plus('Extension!') //Outputs: Hello Extension!
Another example:
import extension from 'extensions.macro'
extension.any.log = obj => () => {
console.log(obj)
return obj
}
'The cosmos is yours 🌌'.log()
//Logs: The cosmos is yours 🌌
Usage
extension.<object constructor name>.<extension name> = <init>
Object constructor name
It's the result of calling .constructor.name
on object the extension is dedicated for
;(15).constructor.name //Outputs: Number
extension.any...
You can write any
instead of constructor name to match any type of object
Extension name
It's the name of the extension you choose
Init
It's the function that takes an object and returns what should extension return
Rules
- Declare extension in module scope
- Extensions do not override object properties
- Be aware of recursive extension
Declare extension in module scope
//...
import curry from '@ramda/curry'
extension.Function.curry = fun => curry(fun) //✔
{
extension.Function.curry = fun => curry(fun) //❌Throws: Error
}
//...
Extensions do not override object properties
extension.any.reduce = obj => reducer => reducer(obj)
'Who let the dogs out!?'.reduce(v => `${v} wow! wow! wow!`)
//Outputs: Who let the dogs out!? wow! wow! wow!
;[1, 2, 3].reduce((total, value) => total + value)
//Outputs: 6
Be aware of recursive called extension
Though you can do it but it does not very performant and is considered to be blocked in future versions
extension.Number.factorial = num => () => {
if (num === 1 || num === 0) return 1
return num * (num - 1).factorial()
}
//Works, but it's bad ❗
Do instead:
const factorial = num => {
if (num === 1 || num === 0) return 1
return num * factorial(num - 1)
}
extension.Number.factorial = num => () => factorial(num)
//Right way ✅
Other features
Extension overloading
You can overload any
extension like so:
extension.any.plus = obj => plusObj => obj + plusObj
extension.String.plus = string => plusString => `${string} + ${plusString}`
'👽'.plus('💩') //Outputs 👽 + 💩
;(5).plus(2) ////Outputs 7
Extension parameters
You might overlook that you needn't return function from extension
extension.Array.last = arr => arr[arr.length - 1]
console.log(['🥞', '💋'].last) //Logs: 💋
To Do
- Add
Import
andExport
feature for extension - Add more reliable
Errors
Proposals
- Add extension setters?