Is it possible to create Kotlin like scope functions in Javascript/Typescript? Is there any library that does it?
Reference: https://kotlinlang.org/docs/reference/scope-functions.html
Is it possible to create Kotlin like scope functions in Javascript/Typescript? Is there any library that does it?
Reference: https://kotlinlang.org/docs/reference/scope-functions.html
No, you can't do that in JavaScript or TypeScript. But depending on why you're trying to do it, destructuring can help.
The closest you can get is to use the deprecated with statement, which adds an object to the top of the scope chain, so any freestanding identifier references are checked against the object's properties:
function example(o) {
with (o) { // deprecated
console.log(answer);
}
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
There are several problems with with, though, which is why it's disallowed in the strict variant of JavaScript (which is the default inside modules, class constructs, and other new scopes created in ES2015+, as well as any function or script with "use strict"; at the beginning).
Another close version is to pass an object to a function that uses destructuring in its parameter list:
function example({answer}) {
console.log(answer);
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
but a major caveat there is that you can't assign new values to properties that way (and worse, if you try — for instance, with answer = 67 — it updates the parameter's value but not the object's property value).
To deal with that, you might use destructuring inside the function instead, with const so you don't forget you can't update the value (or to get an early error if you try):
function example(o) {
const {answer} = o;
console.log(answer);
// answer = 67; // <== Would cause error
// o.answer = 67; // <== Would work
}
const obj = {
answer: 42
};
example(obj); // Outputs 42
https://www.npmjs.com/package/lazymacro
This package provides the feature you need and its implement is pretty simple (through Object.defineProperty see code).
obj.PIPE(f) is similar to let in kotlinobj.PIPETHIS(f) is similar to run in kotlinobj.WITH(f) is similar to also in kotlinobj.WITHTHIS(f) is similar to apply in kotlinThen you can write something like:
["I", "am"]
.WITH(v => v.push("lazynode."))
.WITH(console.log)
.PIPE(v => v.join(" "))
.PIPE(v => console.log(`${v}`))
?.PIPE(v => console.log("null safety features can be used together!"));
AND IN ADDATION
It provides scope functions for Promise, which can save you from the await/then hell
promise.THEN(f)promise.WAIT(f)example:
Promise.resolve({})
.WAIT(async local => local.datax = await getSomeRemoteData())
.WAIT(async local => local.datay = await getSomeRemoteData())
.WAIT(async local => local.dataz = await getSomeRemoteData())
.WAIT(async local => await doSomething(local.datax, local.datay, local.dataz));
While not exactly what you're looking for, a pattern that I use let a lot for in Kotlin is
val thing = nullable?.let{ // case if not null } ?: run { // case if null }
The closest I've come to this in Javascript (well, typescript) in terms of readability and ergonomics is something like:
const thing = some?.deeply?.nested?.nullable?.thing ?? (() => {
// case if null
})
Which gets you halfway there. :)
If anyone is still looking for an answer, there is an excellent library for those scope functions for javascript (I am not affiliated):
You can use Kotlin/js. It allows you to transpile Kotlin code to JavaScript or TypeScript and it is fully interoperable with the JavaScript ecosystem.