我们正在使用 Angular 2 和 TypeScript 构建一个应用程序。我们尝试在可能的情况下静态检查类型。有没有办法检查模板中的类型?考虑以下片段:
<foo [data]="dataObj"></foo>
假设data
在Foo
组件中有某种类型TData
。但是,默认情况下,没有什么能阻止我传递dataObj
不符合TData
. 是否有 Angular 模板的打字稿扩展可以在这种情况下验证类型?
我们正在使用 Angular 2 和 TypeScript 构建一个应用程序。我们尝试在可能的情况下静态检查类型。有没有办法检查模板中的类型?考虑以下片段:
<foo [data]="dataObj"></foo>
假设data
在Foo
组件中有某种类型TData
。但是,默认情况下,没有什么能阻止我传递dataObj
不符合TData
. 是否有 Angular 模板的打字稿扩展可以在这种情况下验证类型?
由于 Angular 9,解决方案是strictTemplates
Angular 编译选项的标志,请参阅模板类型检查指南的严格模式部分。在文件中启用标志: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 上发现了两个问题(issue1和issue2)。据我了解,问题的解决方案取决于渲染器的实现,并且更有可能在下一个版本的角度渲染器(称为Ivy )中解决该问题。这是ivy 渲染器中输入类型检查的功能请求。
引用官方声明:
在模板类型检查阶段,Angular 模板编译器使用 TypeScript 编译器来验证模板中的绑定表达式。
当在模板绑定表达式中检测到类型错误时,模板验证会生成错误消息,类似于 TypeScript 编译器针对 .ts 文件中的代码报告类型错误的方式。
更多信息:
角度模板检查https://angular.io/guide/aot-compiler#binding-expression-validation
然而要激活它,你应该构建应用程序,通过
ng build --aot
或者
ng build --prod
但您也可以在不构建的情况下激活它:
ng serve --aot
Jetbrains 的WebStorm可以做到这一点。
我原来的答案:
如果不像 React 对 JSX 或 TSX 语言扩展那样做一些思考,我认为没有一种可靠的方法可以做到这一点。
typescript 编译器不知道您的 HTML 文件,只会忽略它们。此外,您的模板和控制器代码之间没有强耦合......没有什么可以阻止您在多个控制器中重用相同的模板。
我认为 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
您的组件 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>
您可以使用管道:
export class ObjectTypePipe implements PipeTransform {
transform(value: any, args?: any): string {
if (value != undefined && value != null) {
return value.constructor.name.toString();
}
return "";
}
}
这将允许您进行字符串比较。
如果您使用的是 Visual Studio 代码,则可以尝试语言服务扩展。它仍在大力开发中,您可以在测试版中考虑它。但是当我肯定会说它让我更有效率时。不仅是它的类型检查,而且还有 cmd + 单击组件以转到它们的源。
如果我没记错的话,这个项目最终将被合并到 vscode 中,因为它有点稳定,因为它符合 vscode 的最佳利益,以保持 Angular 开发人员的生产力。
您可以放心扩展的支持,因为它正在由 Angular 团队开发。有关更多信息,请查看此自述文件
编辑: sublime text 和 webstorm 也支持这个。