首页 > 解决方案 > 有没有办法向模板输入变量添加类型断言/注释?

问题描述

背景

我有一个看起来像这样的模板(我正在使用一些组件,它使用它作为重复项目的基础,它是<p-pickList>,但问题并不特定于该组件,仅作为示例)

对于背景,假设我有一个类型Foo并且我的组件有一个foos: Foo[],我将它提供给属性<p-pickList>下的组件[source]并为其做内部*ngFor操作,我所要做的就是提供一个模板

 <ng-template let-foo pTemplate="item">
   ...
   {{ foo.anythingGoesHereWithNoWarningAndNoAutocomplete }}

但是,foo似乎丢失了类型信息。

我是类型安全的忠实拥护者,我喜欢 Intellij(或任何其他编辑器)如果在模板中执行诸如指定无效属性之类的操作,则可以向我显示警告foo

如果我有一个常规的*ngFor,它会推断出的类型foo

<div *ngFor="let foo of foos">
  {{ foo.autoCompleteWorksInMostIDEsAsWellAsWarningIfInvalidProp }}

问题:

  1. 是否有任何语法可以让我提示 的类型let-foo?(希望大多数 IDE 都能识别)。

  2. 如果我不想依赖 IDE,有没有办法让 ng 编译器类型检查foo(由 let-foo 声明)?

tl;博士是否有一种语法可以让我键入注释模板输入变量?例如像这样组成的语法?

let-foo="$implicit as Foo"还是let-foo-type="Foo"

解决方法

一个愚蠢的想法是在我的组件中具有标识功能,例如

identity(foo: Foo): Foo {
  return foo;
}

但是做

{{ identity(foo).fooProp }}

是不是一个很大的改进

{{ (foo as Foo).fooProp }}`

标签: angularangular6

解决方案


让我们看看 Angular 与它有什么相似之处以及它是如何工作的!

<p *ngFor="let number of [{v: 101},{v: 102}, {v: 103}]">{{number.v}}</p>

我们可以在没有*魔法的情况下重写它

<ng-template ngFor let-number [ngForOf]="[{v: 101},{v: 102}, {v: 103}]">
  <p>{{number.v}}</p>
</ng-template>

如果没有观察者 ( ngDoCheck),它可以与(但ngTemplateOutlet 没有类型检查)相同:

<ng-template let-number #templateRef>
  <p>{{number.v}}</p>
</ng-template>
<ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 101}}"></ng-container>
<ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 102}}"></ng-container>
<ng-container *ngTemplateOutlet="templateRef; context: {$implicit: {v: 103}}"></ng-container>

或者我们可以自己创建

// template
<button (click)=create(templateRef)>create</button>
// TS
constructor(private _viewContainerRef: ViewContainerRef) { ... }

create(templateRef: TemplateRef<{$implicit: {v: number;}}>) {
    this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 101}});
    this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 102}});
    this._viewContainerRef.createEmbeddedView(templateRef, {$implicit: {v: 103}});
}

TL;博士

模板类型检查魔法发生在里面viewContainerRef.createEmbeddedView。(例如ngFor);但它假设 templateRef 接受什么。

Angular 可以编译AOT

<p *ngFor="let num of [{v:1}, {v:2}]">
  {{num.does.not.exist.completly}}
</p>

因此,据我了解,我们应该假设模板具有哪些类型,但要检查模板何时实例化(通过createEmbeddedView);


推荐阅读