51

我们正在使用 Angular 2 和 TypeScript 构建一个应用程序。我们尝试在可能的情况下静态检查类型。有没有办法检查模板中的类型?考虑以下片段:

<foo [data]="dataObj"></foo>

假设dataFoo组件中有某种类型TData。但是,默认情况下,没有什么能阻止我传递dataObj不符合TData. 是否有 Angular 模板的打字稿扩展可以在这种情况下验证类型?

4

7 回答 7

16

由于 Angular 9,解决方案是strictTemplatesAngular 编译选项的标志,请参阅模板类型检查指南的严格模式部分。在文件中启用标志:tsconfig.json

{
    ...
    "compilerOptions": { ... },
    "angularCompilerOptions": {
        "strictTemplates": true
        ...
    }
}

原答案:

不幸的是,当前的 Angular 版本似乎没有检查组件输入和事件的类型。您可以使用AOT编译并启用fullTemplateTypeCheck角度编译器选项,该选项执行一些模板类型检查。

启用 fullTemplateTypeCheck 选项src/tsconfig.app.json

{
    "compilerOptions": { ... },
    "angularCompilerOptions": {
        "fullTemplateTypeCheck": true
        ...
    }
}

--aot并使用选项构建(或服务)您的项目

ng build --aot

输入和事件类型检查怎么样,我在 angular bug tracker 上发现了两个问题(issue1issue2)。据我了解,问题的解决方案取决于渲染器的实现,并且更有可能在下一个版本的角度渲染器(称为Ivy )中解决该问题。这是ivy 渲染器中输入类型检查的功能请求。

于 2018-06-20T10:12:13.853 回答
0

引用官方声明:

在模板类型检查阶段,Angular 模板编译器使用 TypeScript 编译器来验证模板中的绑定表达式。

当在模板绑定表达式中检测到类型错误时,模板验证会生成错误消息,类似于 TypeScript 编译器针对 .ts 文件中的代码报告类型错误的方式。

更多信息:

角度模板检查https://angular.io/guide/aot-compiler#binding-expression-validation

然而要激活它,你应该构建应用程序,通过

ng build --aot

或者

ng build --prod

但您也可以在不构建的情况下激活它:

ng serve --aot

于 2019-10-23T12:44:31.863 回答
0

Jetbrains 的WebStorm可以做到这一点。

我原来的答案:

如果不像 React 对 JSX 或 TSX 语言扩展那样做一些思考,我认为没有一种可靠的方法可以做到这一点。

typescript 编译器不知道您的 HTML 文件,只会忽略它们。此外,您的模板和控制器代码之间没有强耦合......没有什么可以阻止您在多个控制器中重用相同的模板。

于 2017-09-11T09:49:46.740 回答
-1

我认为 IDE 或 linter 可能会为您捕捉到这个,但如果有人真的需要这个,一个选择是创建一个 Pipe 来在运行时进行类型检查。

@Pipe({ name: 'typeCheck' })
export class TypeCheckPipe implements PipeTransform {

  transform(value: any, classType: object): any[] {
    if (value &&
      !(value instanceof classType)
    ) {
        throw new TypeError("Input is not instanceof " + classType + 
                            " but was " + typeof(value));
    }
    return value;
  }
}

您可以在这样的组件模板中使用它:

<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>

我发现的唯一问题是我不确定如何将类函数注入到模板中,而不是作为组件的实例。

@Component({
  selector: 'my-app',
  template: `
  <div>
    <custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>
  </div>
  `,
})
export class App {
  coolInput: CoolInput;
  coolInputClass: object = CoolInput;

  constructor() {
    this.coolInput = "This is the wrong type";
  }
}

这是一个 Plunker,说明了工作错误消息(通过区域抛出)。 https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview

于 2017-02-06T22:10:46.880 回答
-1

您的组件 Input() 应该具有类型。假设您有一个列表组件

import {Component, Input, OnInit } from '@angular/core';

import { Items } from '../../../services/Items';

@Component({
  selector: 'my-list',
  templateUrl: './my-list.component.html',
  styleUrls: ['./my-list.component.scss'],
})
export class CategoryListComponent implements OnInit {
  @Input() items: Items;

  constructor() { }

  ngOnInit() { }
}

“Items”应定义为接口并导入

export interface List {
  name: string,
  children: Items[]
}

export interface Item {
  name: string;
  slug: string;
  imageUrl: string;
  children: Item[];
}

现在你可以像这样使用它

<my-list [items]="items"></my-list>
于 2017-11-01T12:11:21.493 回答
-1

您可以使用管道:

export class ObjectTypePipe implements PipeTransform {
    transform(value: any, args?: any): string {
        if (value != undefined && value != null) {
            return value.constructor.name.toString();
        }
        return "";
    }
}

这将允许您进行字符串比较。

于 2017-11-06T09:22:25.070 回答
-1

如果您使用的是 Visual Studio 代码,则可以尝试语言服务扩展。它仍在大力开发中,您可以在测试版中考虑它。但是当我肯定会说它让我更有效率时。不仅是它的类型检查,而且还有 cmd + 单击组件​​以转到它们的源。

如果我没记错的话,这个项目最终将被合并到 vscode 中,因为它有点稳定,因为它符合 vscode 的最佳利益,以保持 Angular 开发人员的生产力。

您可以放心扩展的支持,因为它正在由 Angular 团队开发。有关更多信息,请查看此自述文件

编辑: sublime text 和 webstorm 也支持这个。

于 2017-09-07T07:21:16.530 回答