I had mixed feelings about using, but I’m into it now. I like seeing familiar conventions from other languages I’ve come to love, and it seems like the implementation will likely deliver the same QOL benefits I’m familiar with.<p>On that note, I know it’s contentious, but I’d love to see pattern matching baked in like we have it in Rust (or similar). I’ve come to love ts-pattern so much, and I’m constantly wishing it was part of TypeScript/JavaScript.
I can't help but think this is a clunkier than necessary. With function composition and the try/finally approach described we can get the same thing:<p><pre><code> const doSomeWork = () => {
// some computation here.
}
const withCleanup = (fn, cleanupFn) => {
let x;
try { x = fn() }
finally { cleanupFn() }
return x;
};
const someCleanupFn = () => {
// remove that file or whatever...
};
const doSomeWorkAndCleanup = withCleanup(doSomeWork, someCleanupFn);
</code></pre>
This also provides lots of nice ways to understand what that cleanup behavior was to the caller. We could return an array of the original function return value and the result of the cleanup function. Maybe this reveals a potential new monadic structure that would be useful...<p>I agree doing this in OO, like what's shown in the page's examples, without the execution environment's support is tricky... I'd rather see though a new class to handle this rather than adding this behavior by adding a special method - it seems to put us back in the direction of having lifecycle methods like what React supports in class components that the community has totally moved away from.<p>I think I don't like that triggering the `dispose` method only takes place when the keyword `using` is present. It'd be much cleaner that it is always invoked on any object whose extends `Disposable`. Unless I have that behavior wrong...
This [Symbol.dispose]() stuff is not intuitive to me. What are the brackets for? Is this an object property? Seems like a bad analogue to Swift’s defer and deinit keywords/methods.