我们正在使用Angular 2和TypeScript构建应用程序。我们尝试静态检查可能的类型。有没有办法检查模板中的类型?请考虑以下片段:
<foo [data]="dataObj"></foo>
假设data
组件中的Foo
具有某种类型TData
。但是,默认情况下,没有什么可以阻止我传递不符合dataObj
的{{1}}。是否有Angular模板的typescript扩展,可以在这种情况下验证类型?
答案 0 :(得分:8)
不幸的是,当前的Angular版本似乎不检查组件输入和事件的类型。您可以使用AOT编译并启用fullTemplateTypeCheck角度编译器选项,该选项执行一些模板类型检查。
在src/tsconfig.app.json
中启用fullTemplateTypeCheck选项
{
"compilerOptions": { ... },
"angularCompilerOptions": {
"fullTemplateTypeCheck": true
...
}
}
并使用--aot
选项构建(或服务)您的项目
ng build --aot
关于输入和事件类型检查,我在角度错误跟踪器上发现了两个问题(issue1和issue2)。据我了解,该问题的解决方案取决于渲染器的实现,并且更有可能在称为Ivy的下一版本的角度渲染器中解决该问题。 Here is功能要求在常春藤渲染器中进行输入类型检查。
答案 1 :(得分: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,说明了工作错误消息(通过Zone抛出)。 https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview
答案 2 :(得分:0)
WebStorm可以做到这一点。
我原来的回答:
我认为如果不做一些事情就没有可靠的方法 想想React是否使用该语言的JSX或TSX扩展。
typescript编译器不知道你的HTML文件,并且会 只是忽略它们。而且,你之间没有强大的联系 模板和控制器代码......没有什么能阻止你 从多个控制器重用相同的模板。
答案 3 :(得分:0)
引用官方声明:
在模板类型检查阶段,Angular模板编译器使用TypeScript编译器来验证模板中的绑定表达式。
在模板绑定表达式中检测到类型错误时,模板验证会产生错误消息,类似于TypeScript编译器根据.ts文件中的代码报告类型错误。
更多信息:
角度模板检查https://angular.io/guide/aot-compiler#binding-expression-validation
要激活它,您应该通过以下方式构建应用程序
ng build --aot
或
ng build --prod
但是您也可以不构建而将其激活:
ng serve --aot
答案 4 :(得分:-1)
如果您使用的是visual studio代码,则可以试用language service扩展程序。它仍然处于重大发展阶段,您可以将其视为测试版。但是,当我肯定会说它让我更有成效。不仅要进行类型检查,还要使用cmd +单击组件来查看其来源。
如果我没有弄错的话,this项目最终会被合并到vscode它自己,因为它有点稳定,因为它在vscode的最佳利益是保持角度开发人员的工作效率。
您可以放心,我们可以放心,因为角色团队正在努力解决这个问题。有关详细信息,请查看此readme
编辑: sublime text和webstorm也支持此功能。
答案 5 :(得分:-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() { }
}
“项目”应定义为界面并导入
export interface List {
name: string,
children: Items[]
}
export interface Item {
name: string;
slug: string;
imageUrl: string;
children: Item[];
}
现在你可以像这样使用它
<my-list [items]="items"></my-list>
答案 6 :(得分:-1)
你可以使用Pipe:
export class ObjectTypePipe implements PipeTransform {
transform(value: any, args?: any): string {
if (value != undefined && value != null) {
return value.constructor.name.toString();
}
return "";
}
}
然后,这将允许您进行字符串比较。