Skip to content

[TS] filter(Boolean) loses type information, TypeScript 3.5 makes it worse #4959

@rkirov

Description

@rkirov

Bug Report

More of a heads up, than a bug report, but this has been a major PITA for upgrading Google internal to TS 3.5, so I wanted to have a discussion here too.

Current Behavior
With TS3.4 pipe(filter(Boolean)) loses type information, everything after it is of type any. See stackblitz below:

const source = of('World').pipe(
  map(x => `Hello ${x}!`),
  filter(Boolean),
  map(y => y.madeup)  // no type error
);

The type of Boolean in lib.d.ts is

interface BooleanConstructor {
    new (value?: any): Boolean;
    (value?: any): boolean;
    readonly prototype: Boolean;
}

With TS3.5 Boolean is typed as

interface BooleanConstructor {
    new (value?: any): Boolean;
    <T>(value?: T): boolean;
    readonly prototype: Boolean;
}

https://github.com/microsoft/TypeScript/blob/master/lib/lib.es5.d.ts#L536

However, in most cases it appears <T> is not inferrable (I don't blame TS, this is really round-about), so TS3.5 pick the new default unknown, which in turn makes the type for the next operation unknown from previously any causing many compilation failures.

Reproduction
https://stackblitz.com/edit/rxjs-erah82

Possible Solution
I have been recommending replacing filter(Boolean) with the following more explicit workaround filter((x): x is OutputType => !!x) where OutputType is explicitly spelled out the expected type in the next operation in the chain.

Or maybe once microsoft/TypeScript#16655 (comment) lands filter(Boolean) will just work for Rxjs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    TSIssues and PRs related purely to TypeScript issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions