ava: ObservableLike type definition is incorrect

Description

As I commented in this closed issue https://github.com/avajs/ava/issues/1685#issuecomment-520885556, the ObservableLike definition in ava 2.2.0 is incorrect. It expects the property [Symbol.observable]() but this property is not in rxjs Observable type.

Test Source

import { of } from 'rxjs';

test('foo', t => {
  return of(3).pipe(tap(() => t.pass()));
});

Error Message & Stack Trace

  error TS2345: Argument of type '"foo"' is not assignable to parameter of type 'OneOrMoreMacros<[(t: ExecutionContext<{}>) => Observable<number>], {}>'.

  test('foo', t => {
         ~~~~~

Removing the [Symbol.observable](): ObservableLike; solves it though…

When trying to enforce the ObservableLike type with return of(3).pipe(tap(() => t.pass())) as ObservableLike;. TypeScript would throw

Conversion of type ‘Observable<number>’ to type ‘ObservableLike’ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown’ first. Property ‘[Symbol.observable]’ is missing in type ‘Observable<number>’ but required in type ‘ObservableLike’

So basically, [Symbol.observable]() is not in rxjs Observable type definition. Can we then reopen this issue?

Expected behaviour

The returned Observable should match the ObservableLike type and the t => ... should not infer the type OneOrMoreMacros.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (18 by maintainers)

Most upvoted comments

Type definitions aside, right now, AVA supports “observable” test implementations. This is built on the following detection logic:

https://github.com/sindresorhus/is-observable/blob/ca9746cc390d7f941afe5af8a6d71ac114392ebe/index.js#L9:L15

if (value[Symbol.observable] && value === value[Symbol.observable]()) {
	return true;
}


if (value['@@observable'] && value === value['@@observable']()) {
	return true;
}

Only when the object returned by the test implementation has either of these properties will we subscribe to it.

So, sure, we could remove Symbol.observable from the type definition. That does not give any guarantees though as to what return value is recognized as an observable at runtime. This, I imagine, is why Symbol.observable was added to the type definition to begin with.

@micaelmbagira, regarding this:

Symbol.observable is […] not even used anymore in RxJS (which is the most used Observable library)

How does RxJS “tag” observables then? The '@@observable' string? I’m happy to change the type to recognize that instead, though we may want to push updates to AVA’s observable dependencies as well to remove the Symbol.observable checks.

Technically this is also a breaking change in our type definition although the subset of folks who would be affected probably wouldn’t mind it 😄

@micaelmbagira I think if we say any implementation result that has a subscribe() method, which takes error and complete callbacks, then we can treat it as an observable and convert it to a promise?