Skip to content

Type Guards on this should affect type parameters #28889

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

Closed
SLaks opened this issue Dec 7, 2018 · 3 comments
Closed

Type Guards on this should affect type parameters #28889

SLaks opened this issue Dec 7, 2018 · 3 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@SLaks
Copy link

SLaks commented Dec 7, 2018

TypeScript Version: 3.2.1-insiders.20181128

Search Terms: type guard this generic

Summary

In a class MyClass<T>, a type guard of the form this is MyClass<T & Foo> should constrain T to extend Foo.

Alternative

It might make more sense to instead allow type guards on generic parameters; eg, isFoo(): T is Foo.

Code

class FooBuilder<TWith> {
    private bar?: number;
    private qux?: number;

    private whatIsTWith?: TWith

    private hasBar(): this is FooBuilder<TWith | WithBar>{
        return !!this.bar;
    }
    private hasQux(): this is FooBuilder<TWith | WithQux>{
        return !!this.qux;
    }

    public specify(options: Options<TWith>) {
        if (this.hasBar()) {
            options.bar;
            this.whatIsTWith;
        }
        if (this.hasQux()) {
            options.qux;
        }
    }
}

class WithBar { private noStructuralTyping: undefined; }
class WithQux { private noStructuralTyping: undefined; }

type Options<TWith> =
      (WithBar extends TWith ? { bar: string } : {})
    & (WithQux extends TWith ? { qux: string } : {});

// Usage:
new FooBuilder<WithBar | WithQux>().specify({ bar: '', qux: '' });

Expected behavior:

Inside if (this.hasBar()), TWith should be constrained to extend WithBar and options.bar should exist.

Actual behavior:

options still has no properties.

With stricter compilation options, this.whatIsTWith has conflicting definitions.

Playground Link: Link
Related Issues: #14817

@weswigham
Copy link
Member

options is unrelated to this - there's no dependency between them. Narrowing this won't narrow options.

@weswigham weswigham added the Question An issue which isn't directly actionable in code label Dec 7, 2018
@SLaks
Copy link
Author

SLaks commented Dec 28, 2018

If I move options to a field, this.options still isn't narrowed.

I'm expecting it to affect the TWith type parameter, in all usages.

@typescript-bot
Copy link
Collaborator

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

3 participants