Angular structural directive context template type checking

Viewed 781

I can't seem to make angular template autocomplete work, can anyone help me out understanding what am I missing or doing wrong?

<div *ngVar="ok as xd">
    <!-- xd is not giving any autocomplete / typecheck, hover giving "any" type -->
    {{ xd.item }}
</div>

I pretty much went on the ngIf and async pipe source code trying to understand what was going on and made this simple directive just to facilitate my life with async subscriptions (which are kind of a pain with the ngIf.
Not having type safety is equally a pain tho x)

type NgVarContext<T> = { ngVar: T; $implicit: undefined };

@Directive({
    selector: "[ngVar]",
})
export class NgVar<T> {
    context: NgVarContext<T> = { ngVar: undefined, $implicit: undefined };
    _subscription: Subscription;

    constructor(
        private cdr: ChangeDetectorRef,
        template: TemplateRef<NgVarContext<T>>,
        viewContainer: ViewContainerRef
    ) {
        viewContainer.createEmbeddedView(template, this.context);
    }

    @Input()
    set ngVar(input: Observable<T>) {
        if (this._subscription) return;
        this._subscription = input.subscribe((item) => {
            if (item !== this.context.ngVar) {
                this.context.ngVar = item;
                this.cdr.markForCheck();
            }
        });
    }

    static ngTemplateGuard_ngVar: "binding";

    static ngTemplateContextGuard<T>(dir: NgVar<T>, ctx: NgVarContext<T>): ctx is NgVarContext<T> {
        return true;
    }
}

2 Answers

Just if you are not aware (writing this as a answer because I cannot comment with <50 reputation): If you enable the experimental ivy language service in vscode, this is already working for me: Basically the same implementation as written here.

enter image description here

See: https://twitter.com/angular/status/1357403631901937672

Its me, the OP

There is no problem with the directive.

The problem is that the angular language service is not updated yet to infer those types (they announced it supporting ivy recently, so this should work in a few months I hope).

I will update the answer when it is fixed.

Related