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

Infer type guard from predicate for functions accepting type guards. #19468

Closed
martaver opened this issue Oct 25, 2017 · 5 comments
Closed

Infer type guard from predicate for functions accepting type guards. #19468

martaver opened this issue Oct 25, 2017 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@martaver
Copy link

It would be great to avoid the ceremony of having to declare separate type guards for functions accepting a type guard as an argument.

Consider functions like Array.filter or Observable.filter being used to filter a union type with discriminant:

type FooBar = { type: 'foo' } | { type: 'bar' };
const isFoo = <(fb: FooBar) => fb is { type: 'foo'}>(fb => fb.type == "foo");
const fooBar$: Observable<FooBar> = { /* ... */ };
const foo$ = fooBar$.filter(isFoo); //We can use the type guard 'isFoo' to narrow the type to Foo.

However this is quite a lot of wiring for something that anywhere else is quite straight forward. In an if/else or switch block, a type guard isn't necessary... Typescript infers the type from the predicate:

if(fb.type === 'foo') {
    //'fb' is { type: 'foo' }
}

Having to declare the type guard also requires us to 'repeat' out the shape of the type which can be quite painful if it isn't a type alias or class... i.e. we have to explicitly write `fb is { type: 'foo' }.

Typescript should be able to infer that the correct type is { type: 'foo' } from the supplied predicate.

In such an ideal world, we should be able to simply write:

const foo$ = fooBar$.filter(fb => fb.type === 'foo');

If Typescript requires us to explicitly opt-in the function as a type-guard, then it should be possible to do so without explicitly repeating the type in the declaration. Maybe something like:

const foo$ = fooBar$.filter(<fb is>(fb => fb.type === 'foo'));
@jcalz
Copy link
Contributor

jcalz commented Oct 25, 2017

Duplicate of #10734 and #14891 and #5101 (with a relevant comment)

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Oct 25, 2017
@DanielRosenwasser
Copy link
Member

Thanks for finding that @jcalz

@martaver
Copy link
Author

To clarify, I'm looking for a general solution that doesn't require explicit definition of the narrowed guard type, not just an overload to Array.filter...

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

1 similar comment
@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants