# The Template Type Checking Engine
The `typecheck` package is concerned with template type-checking, the process by which the compiler determines and understands the TypeScript types of constructs within component templates. It's used to perform actual type checking of templates (similarly to how TypeScript checks code for type errors). It also provides the `TemplateTypeChecker` API which is a conceptual analogue to TypeScript's own `ts.TypeChecker`, exposing various semantic details about template types to consumers such as the Angular Language Service.
The template type-checking engine is complex, as TypeScript itself is not very pluggable when it comes to the type system. The main algorithm for template type-checking is as follows:
1. The input `ts.Program` is analyzed, and information about directives/pipes as well as candidate templates is collected.
2. Each candidate template is converted into a "type-check block", or TCB, a TypeScript function that semantically describes the operations in the template as well as their types.
3. A derivative `ts.Program` is created from the user's input program from step 1, plus the newly generated TCBs.
4. TypeScript is asked to produce diagnostics for the TCBs, which arise from type errors within the template.
5. TCB diagnostics are converted to template diagnostics and reported to the user.
This algorithm relies extensively on TypeScript's ability to rapidly type check incremental changes in a `ts.Program` for its performance characteristics. Much of its design is optimized to ensure TypeScript has to do the minimum incremental work to check the new `ts.Program`.
## Type Check Blocks
To understand and check the types of various operations and structures within templates, the `typecheck` system maps them to TypeScript code, encoding them in such a way as to express the intent of the operation within the type system.
TCBs are not ever emitted, nor are they referenced from any other code (they're unused code as far as TypeScript is concerned). Their _runtime_ effect is therefore unimportant. What matters is that they express to TypeScript the type relationships of directives, bindings, and other entities in the template. Type errors within TCBs translate directly to type errors in the original template.
### Theory
Given a component `SomeCmp`, its TCB takes the form of a function:
```typescript
function tcb(this: SomeCmp): void {
// TCB code
}
```
Encoding the TCB as a function serves two purposes:
1. It provides a lexical scope in which to declare variables without fear of collisions.
2. It provides a convenient location (the parameter list) to declare the component context.
The component context is the theoretical component instance associated with the template. Expressions within the template often refer to properties of this component.
For example, if `SomeCmp`'s template has an interpolation expression `{{foo.bar}}`, this suggests that `SomeCmp` has a property `foo`, and that `foo` itself is an object with a property `bar` (or in a type sense, that the type of `SomeCmp.foo` has a property `bar`).
Such a binding is expressed in the TCB function, using the `this` parameter as the component instance:
```typescript
function tcb(this: SomeCmp): void {
'' + this.foo.bar;
}
```
If `SomeCmp` does not have a `foo` property, then TypeScript will produce a type error/diagnostic for the expression `this.foo`. If `this.foo` does exist, but is not of a type that has a `bar` property, then TypeScript will catch that too. By mapping the template expression `{{foo.bar}}` to TypeScript code, the compiler has captured its _intent_ in the TCB in a way that TypeScript can validate.
#### Types of template declarations
Not only can a template consume properties declared from its component, but various structures within a template can also be considered "declarations" which have types of their own. For example, the template:
```html
<input #name>
{{name.value}}
```
declares a single `<input>` element with a local ref `#name`, meaning that within this template `name` refers to the `<input>` element. The `{{name.value}}` interpolation is reading the `value` property of this element.
Within the TCB, the `<input>` element is treated as a declaration, and the compiler leverages the powerful type inference of `document.createElement`:
```typescript
function tcb(this: SomeCmp): void {
var _t1 = document.createElement('input');
'' + _t1.value;
}
```
The `_t1` variable represents the instance of the `<input>` element within the template. This statement will never be executed, but its initialization expression is used to infer a correct type of `_t1` (`HTMLInputElement`), using the `document.createElement` typings that TypeScript provides.
By knowing the type of this element, the expression involving the `name` local ref can be translated into the TCB as `_t1.value`. TypeScript will then validate that `_t1` has a `value` property (really, that the `HTMLInputElement` type has a `value` property).
#### Directive types
Just like with HTML elements, directives present on elements within the template (including those directives which are components) are treated as declarations as well. Consider the template:
```html
<other-cmp [foo]="bar"></other-cmp>
```
The TCB for this template looks like:
```typescript
function tcb(this: SomeCmp): void {
var _t1: OtherCmp = null!;
_t1.foo = this.bar;
}
```
Since `<other-cmp>` is a component, the TCB declares `_t1` to be of that component's type. This allows for the binding `[foo]="bar"` to be expressed in TypeScript as `_t1.foo = this.bar` - an assignment to `OtherCmp`'s `@Input` for `foo` of the `bar` property from the template's context. TypeScript can then type check this operation and produce diagnostics if the type of `this.bar` is not assignable to the `_t1.foo` property which backs the `@Input`.
#### Generic directives & type constructors
The above declaration of `_t1` using the component's type only works when the directive/component class is not generic. If `OtherCmp` were declared as:
```typescript
export class OtherCmp<T> {
...
}
```
then the compiler could not write
```typescript
var _t1: OtherCmp<?> = ...;
```
without picking a value for the generic type parameter `T` of `OtherCmp`. How should the compiler know what type the user intended for this component instance?
Ordinarily, for a plain TypeScript class such as `Set<T>`, the generic type parameters of an instance are determined in one of two ways:
1. Directly, via construction: `new Set<string>()`
2. Indirectly, via inference from constructor parameters: `new Set(['foo', 'bar']); // Set<string>`
For directives, neither of these options makes sense. Users do not write direct constructor calls to directives in a template, so there is no mechanism by which they can specify generic types directly. Directive constructors are also dependency-injected, and generic types cannot be used as DI tokens and so they cannot be inferred from DI.
Instead, conceptually, the generic type of a directive depends on the types bound to its _inputs_. This is immediately evident for a directive such as `NgFor`:
```typescript
@Directive({selector: '[ngFor]'})
export class NgFor<T> {
@Input() ngForOf!: Iterable<T>;
}
```
(Note: the real `NgFor` directive is more complex than the simplistic version examined here, but the same principles still apply)
In this case, the `T` type parameter of `NgFor` represents the value type of the `Iterable` over which we're iterating. This depends entirely on the `Iterable` passed to `NgFor` - if the user passes a `User[]` array, then this should conceptually create an `NgFor<User>` instance. If they pass a `string[]` array, it should be an `NgFor<string>` instead.
To infer a correct type for a generic directive, the TCB system generates a **type constructor** for the directive. The type constructor is a "fake" constructor which can be used to infer the directive type base
没有合适的资源?快使用搜索试试~ 我知道了~
angularjs Web页面框架 v17.2.3.zip
共2000个文件
html:531个
md:517个
json:357个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 188 浏览量
2024-03-18
21:27:30
上传
评论
收藏 92.97MB ZIP 举报
温馨提示
angularjs Web页面框架 v17.2.3.zip
资源推荐
资源详情
资源评论
收起资源包目录
angularjs Web页面框架 v17.2.3.zip (2000个子文件)
gumby.css 169KB
base.css 6KB
styles.css 2KB
heroes.component.css 1KB
heroes.component.css 1KB
styles.css 1KB
hero-list-page.component.css 1KB
app.css 1KB
app.css 1KB
app.css 1KB
app.animations.css 1KB
app.animations.css 1KB
heroes.component.css 1KB
details.component.css 1KB
app.component.css 1KB
details.component.css 1KB
details.component.css 1KB
details.component.css 1KB
hero-list.component.css 1KB
heroes.component.css 1KB
heroes.component.css 1KB
heroes.component.css 1KB
heroes.component.css 1003B
crisis-list.component.css 960B
movie-list.component.css 958B
dashboard.component.css 917B
hero-list.component.css 882B
heroes.component.css 867B
dashboard.component.css 862B
app.component.css 862B
app.component.css 787B
app.component.css 777B
dashboard.component.css 767B
styles.1.css 751B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
home.component.css 746B
hero-search.component.css 733B
sample.css 714B
app.css 686B
app.component.css 656B
hero-search.component.css 611B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
housing-location.component.css 583B
hero-details.component.css 572B
hero-tax-return.component.css 554B
hero-detail.component.css 510B
app.component.css 503B
dashboard.component.css 468B
hero-detail.component.css 465B
querying.component.css 449B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
styles.css 443B
dashboard-hero.component.css 428B
architecture.css 427B
hero-list.component.css 410B
forms.css 405B
hero-detail.component.css 403B
app.component.css 397B
sample.css 387B
hero-detail.component.css 380B
app.component.css 378B
messages.component.css 375B
app.component.css 371B
user-input-styles.css 366B
sample.css 356B
app.component.css 356B
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
资源评论
芝麻粒儿
- 粉丝: 6w+
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功