typescript 在 Angular 2 模板中进行类型检查
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33668739/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Type checking in Angular 2 templates
提问by jfu
We are building an application in Angular 2 and TypeScript. We try to statically check types where it is possible. Is there any way to check types in templates? Consider the following fragment:
我们正在用 Angular 2 和 TypeScript 构建一个应用程序。我们尝试在可能的情况下静态检查类型。有没有办法检查模板中的类型?考虑以下片段:
<foo [data]="dataObj"></foo>
Assume that data
in Foo
component has some type TData
. However, by default, nothing prevents me from passing dataObj
that does not conform to TData
. Is there a typescript extension for Angular templates that would verify the types in such a case?
假设data
inFoo
组件具有某种类型TData
。但是,默认情况下,没有什么可以阻止我传递dataObj
不符合TData
. 在这种情况下,是否有用于 Angular 模板的打字稿扩展来验证类型?
回答by Valeriy Katkov
Since Angular 9 the solution is strictTemplates
flag of Angular compile options, see Strict modesection of Template type checkingguide. Enable the flag in tsconfig.json
file:
由于 Angular 9 解决方案是strictTemplates
Angular 编译选项的标志,请参阅模板类型检查指南的严格模式部分。启用文件中的标志:tsconfig.json
{
...
"compilerOptions": { ... },
"angularCompilerOptions": {
"strictTemplates": true
...
}
}
Original answer:
原答案:
Unfortunately, It seems that current Angular version doesn't check types of component inputs and events. You can use AOTcompilation and enable fullTemplateTypeCheckangular compiler option, which performs some template type checking.
不幸的是,当前的 Angular 版本似乎不检查组件输入和事件的类型。您可以使用AOT编译并启用fullTemplateTypeCheck角度编译器选项,它执行一些模板类型检查。
Enable fullTemplateTypeCheck option in src/tsconfig.app.json
在中启用 fullTemplateTypeCheck 选项 src/tsconfig.app.json
{
"compilerOptions": { ... },
"angularCompilerOptions": {
"fullTemplateTypeCheck": true
...
}
}
And build (or serve) your project with --aot
option
并使用--aot
选项构建(或提供)您的项目
ng build --aot
What about inputs and events type checking, I found two issues on angular bug tracker (issue1and issue2). As I understand, the solution of the problem depends on renderer implementation, and more likely that the problem may be fixed in next version of angular renderer, called Ivy. Here isfeature request for inputs type checking in ivy renderer.
什么输入和事件类型检查,我发现了角的bug跟踪系统(两个问题issue1和issue2)。据我了解,问题的解决方案取决于渲染器的实现,更有可能的是,该问题可能会在下一个名为Ivy的角度渲染器版本中得到解决。这是常春藤渲染器中输入类型检查的功能请求。
回答by Sinisa Rudan
to quote the official statement:
引用官方声明:
In the template type-checking phase, the Angular template compiler uses the TypeScript compiler to validate the binding expressions in templates.
Template validation produces error messages when a type error is detected in a template binding expression, similar to how type errors are reported by the TypeScript compiler against code in a .ts file.
在模板类型检查阶段,Angular 模板编译器使用 TypeScript 编译器来验证模板中的绑定表达式。
当在模板绑定表达式中检测到类型错误时,模板验证会产生错误消息,类似于 TypeScript 编译器针对 .ts 文件中的代码报告类型错误的方式。
More at:
更多在:
Angular Template checking https://angular.io/guide/aot-compiler#binding-expression-validation
Angular 模板检查https://angular.io/guide/aot-compiler#binding-expression-validation
Yet to activate it, you should build the app, by
然而要激活它,你应该构建应用程序,通过
ng build --aot
or
或者
ng build --prod
ng build --prod
but you can also activate it without building:
但您也可以在不构建的情况下激活它:
ng serve --aot
ng serve --aot
回答by Victor H?gemann
WebStormfrom Jetbrains can do that.
Jetbrains 的WebStorm可以做到这一点。
My original answer:
我原来的回答:
I don't think there's a reliable way to do that without doing some think like React does with the JSX or TSX extension to the language.
The typescript compiler doesn't know about your HTML files, and will just ignore them. Also, there's no strong coupling between your templates and the Controller code... there's nothing preventing you from reusing the same template across several controllers.
我不认为有一种可靠的方法可以做到这一点,而无需像 React 那样对语言的 JSX 或 TSX 扩展进行一些思考。
打字稿编译器不知道您的 HTML 文件,只会忽略它们。此外,您的模板和控制器代码之间没有强耦合……没有什么可以阻止您在多个控制器之间重用相同的模板。
回答by Mackelito
Your components Input() should have the type. Let's say you have a list component
您的组件 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" should be defined as a interface and imported
“项目”应定义为接口并导入
export interface List {
name: string,
children: Items[]
}
export interface Item {
name: string;
slug: string;
imageUrl: string;
children: Item[];
}
now you can use it like this
现在你可以像这样使用它
<my-list [items]="items"></my-list>
回答by Corrigan
You could use a Pipe:
您可以使用管道:
export class ObjectTypePipe implements PipeTransform {
transform(value: any, args?: any): string {
if (value != undefined && value != null) {
return value.constructor.name.toString();
}
return "";
}
}
This would then allow you to do a string comparison.
这将允许您进行字符串比较。
回答by kevinrstone
I think an IDE or linter might catch this for you, but if someone really needs this, one option would be to create a Pipe to do the type checking at run time.
我认为 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;
}
}
You can use it in a component template like this:
您可以在组件模板中使用它,如下所示:
<custom-component [coolInput]="coolInput | typeCheck:coolInputClass"></custom-component>
The only catch I found is that I'm not sure how to inject the class function into the template other than as an instance of the 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";
}
}
Here is a Plunker illustrating the working error message (thrown via Zone). https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview
这是一个说明工作错误消息的 Plunker(通过 Zone 抛出)。 https://plnkr.co/edit/WhoKSdoKUFvNbU3zWJy6?p=preview
回答by realappie
If you are using visual studio code, you could try out the language serviceextension. Its still under heavy development, and you could consider it in beta. But when I would definitely say that it have made me more productive. Not only its type checking, but also cmd + clicking components to go to their source.
如果您使用的是 Visual Studio 代码,则可以尝试语言服务扩展。它仍在大力开发中,您可以考虑将其用于测试版。但是当我肯定地说它让我更有效率时。不仅是它的类型检查,还有 cmd + 单击组件以转到它们的源代码。
If I am not mistaken, thisproject will eventually be merged to vscode it self when its somewhat stable as its in vscode's best interest to keep angular developers productive.
如果我没记错的话,这个项目最终会被合并到 vscode 本身,因为它有点稳定,因为它符合 vscode 的最大利益,以保持 angular 开发人员的生产力。
You can rest assured about the extension's support because it's being worked on by the angular team. For more information checkout this readme
您可以放心扩展的支持,因为它正在由 angular 团队开发。有关更多信息,请查看此自述文件
Edit:sublime text and webstorm support this too.
编辑:sublime text 和 webstorm 也支持这一点。