Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add [Symbol.dispose] alias to Disposable class #1203

Open
DavidANeil opened this issue Aug 8, 2023 · 3 comments
Open

Add [Symbol.dispose] alias to Disposable class #1203

DavidANeil opened this issue Aug 8, 2023 · 3 comments

Comments

@DavidANeil
Copy link
Contributor

With explicit resource management being added to the language in the near future (supported in TypeScript 5.2), it would be nice to be able to use the using keyword with closure-library Disposables.

I think this would be as simple as this change:

if (typeof Symbol === 'function' && typeof Symbol.dispose === 'symbol') {
  goog.Disposable.prototype[Symbol.dispose] = goog.Disposable.prototype.dispose;
}

I can make this change (with some actual comments) if no one objects.

@shicks
Copy link
Member

shicks commented Aug 10, 2023

While the general ideas are related, it's not clear to me that (in practice) this would actually help much. In particular, goog.Disposable objects tend to live for a medium-to-long amount of time, typically bounded by a "parent object"'s lifetime, which is a pretty different paradigm than a function scope. Given that, I don't see how linking these things would be useful.

In general, Disposable is a pretty archaic/crufty class that we're mostly trying to move away from, so I'm inclined to avoid making this sort of change to it. Can you provide some more concrete use cases in the context of an actual application that would benefit from this?

@DavidANeil
Copy link
Contributor Author

DavidANeil commented Aug 10, 2023

Sure, and yeah we have a lot of Disposables that live a long time.
The most obvious case is our unit tests:

it('should do stuff', () => {
    using injector = createInjector();
    const item = injector.get(UnitUnderTest);
   // test
});

vs.

it('should do stuff', () => {
    const injector = createInjector();
    const item = injector.get(UnitUnderTest);
    // test

    injector.dispose();
});

It would also be convenient in occasional functions that create short lived versions of classes that are disposable, just to do some processing, get a result, and return the result.

function f() {
    using someDisposable = new SomeDisposable();
    return someDisposable.someComputation();
}

vs.

function f() {
    const someDisposable = new SomeDisposable();
    const result = someDisposable.someComputation();
    someDisposable.dispose();
    return result;
}

Neither of these cases actually need the try {} finally {} behavior, as exceptions are rare and leaks aren't catastrophic, but having it certainly wouldn't harm anything.

@shicks
Copy link
Member

shicks commented Aug 17, 2023

Thanks for those use cases. Presumably Closure Compiler will want to transpile using syntax, so it will likely be polyfilling Symbol.dispose, which we'd want to somehow piggyback on. Given the coordination requirements, we need to do a bit of designing internally, but we'll be looking into it this next quarter or so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants