Don't use untilDestroyed.

takeUntilDestroyed was added to @angular/core in Angular 16.

Migrating

Inside of an injection context

In the majority of cases the uses are exactly the same. There are exceptions noted below.

@UntilDestroy()
export class MyComponent() {
  constructor() {
    // console log every second
    interval(1000)
      .pipe(untilDestroyed(this))
      .subscribe(console.log)
  
}

becomes

export class MyComponent() {
  constructor() {
    interval(1000)
      .pipe(takeUntilDestroyed())
      .subscribe(console.log)
  }
}

Outside of an injection context

If calling takeUniltDestroyed outside of a constructor or a property initializer you will also need to pass a reference to the DestroyRef. Failing to do so will cause a runtime exception.

export class MyComponent() {
  // needed only when calling `takeUntilDestroyed` outside of an injection context
  private destroyRef = inject(DestroyRef);
  
  //  the component has a button that invokes this method
  startLoggingNumbersAfterButtonClick() {
    interval(1000)
      .pipe(takeUntilDestroyed(this.destroyRef)) // need a destroy ref here!
      .subscribe(console.log)
  }
}

What the heck is an injection context?

Injection context from the Angular docs.

The takeUntilDestroyed method will inject the DestroyRef automatically when it’s inside an injection context:

https://github.com/angular/angular/blob/main/packages/core/rxjs-interop/src/take_until_destroyed.ts#L24-L27