/
api.ts
256 lines (225 loc) Β· 8.76 KB
/
api.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {BoundTarget, DirectiveMeta, SchemaMetadata} from '@angular/compiler';
import * as ts from 'typescript';
import {Reference} from '../../imports';
import {TemplateGuardMeta} from '../../metadata';
import {ClassDeclaration} from '../../reflection';
/**
* Extension of `DirectiveMeta` that includes additional information required to type-check the
* usage of a particular directive.
*/
export interface TypeCheckableDirectiveMeta extends DirectiveMeta {
ref: Reference<ClassDeclaration>;
queries: string[];
ngTemplateGuards: TemplateGuardMeta[];
coercedInputFields: Set<string>;
hasNgTemplateContextGuard: boolean;
}
/**
* Metadata required in addition to a component class in order to generate a type check block (TCB)
* for that component.
*/
export interface TypeCheckBlockMetadata {
/**
* A unique identifier for the class which gave rise to this TCB.
*
* This can be used to map errors back to the `ts.ClassDeclaration` for the component.
*/
id: string;
/**
* Semantic information about the template of the component.
*/
boundTarget: BoundTarget<TypeCheckableDirectiveMeta>;
/*
* Pipes used in the template of the component.
*/
pipes: Map<string, Reference<ClassDeclaration<ts.ClassDeclaration>>>;
/**
* Schemas that apply to this template.
*/
schemas: SchemaMetadata[];
}
export interface TypeCtorMetadata {
/**
* The name of the requested type constructor function.
*/
fnName: string;
/**
* Whether to generate a body for the function or not.
*/
body: boolean;
/**
* Input, output, and query field names in the type which should be included as constructor input.
*/
fields: {inputs: string[]; outputs: string[]; queries: string[];};
/**
* `Set` of field names which have type coercion enabled.
*/
coercedInputFields: Set<string>;
}
export interface TypeCheckingConfig {
/**
* Whether to check the left-hand side type of binding operations.
*
* For example, if this is `false` then the expression `[input]="expr"` will have `expr` type-
* checked, but not the assignment of the resulting type to the `input` property of whichever
* directive or component is receiving the binding. If set to `true`, both sides of the assignment
* are checked.
*
* This flag only affects bindings to components/directives. Bindings to the DOM are checked if
* `checkTypeOfDomBindings` is set.
*/
checkTypeOfInputBindings: boolean;
/**
* Whether to use strict null types for input bindings for directives.
*
* If this is `true`, applications that are compiled with TypeScript's `strictNullChecks` enabled
* will produce type errors for bindings which can evaluate to `undefined` or `null` where the
* inputs's type does not include `undefined` or `null` in its type. If set to `false`, all
* binding expressions are wrapped in a non-null assertion operator to effectively disable strict
* null checks. This may be particularly useful when the directive is from a library that is not
* compiled with `strictNullChecks` enabled.
*
* If `checkTypeOfInputBindings` is set to `false`, this flag has no effect.
*/
strictNullInputBindings: boolean;
/**
* Whether to check text attributes that happen to be consumed by a directive or component.
*
* For example, in a template containing `<input matInput disabled>` the `disabled` attribute ends
* up being consumed as an input with type `boolean` by the `matInput` directive. At runtime, the
* input will be set to the attribute's string value, which is an empty string for attributes
* without a value, so with this flag set to `true`, an error would be reported. If set to
* `false`, text attributes will never report an error.
*
* Note that if `checkTypeOfInputBindings` is set to `false`, this flag has no effect.
*/
checkTypeOfAttributes: boolean;
/**
* Whether to check the left-hand side type of binding operations to DOM properties.
*
* As `checkTypeOfBindings`, but only applies to bindings to DOM properties.
*
* This does not affect the use of the `DomSchemaChecker` to validate the template against the DOM
* schema. Rather, this flag is an experimental, not yet complete feature which uses the
* lib.dom.d.ts DOM typings in TypeScript to validate that DOM bindings are of the correct type
* for assignability to the underlying DOM element properties.
*/
checkTypeOfDomBindings: boolean;
/**
* Whether to infer the type of the `$event` variable in event bindings for directive outputs or
* animation events.
*
* If this is `true`, the type of `$event` will be inferred based on the generic type of
* `EventEmitter`/`Subject` of the output. If set to `false`, the `$event` variable will be of
* type `any`.
*/
checkTypeOfOutputEvents: boolean;
/**
* Whether to infer the type of the `$event` variable in event bindings for animations.
*
* If this is `true`, the type of `$event` will be `AnimationEvent` from `@angular/animations`.
* If set to `false`, the `$event` variable will be of type `any`.
*/
checkTypeOfAnimationEvents: boolean;
/**
* Whether to infer the type of the `$event` variable in event bindings to DOM events.
*
* If this is `true`, the type of `$event` will be inferred based on TypeScript's
* `HTMLElementEventMap`, with a fallback to the native `Event` type. If set to `false`, the
* `$event` variable will be of type `any`.
*/
checkTypeOfDomEvents: boolean;
/**
* Whether to infer the type of local references to DOM elements.
*
* If this is `true`, the type of a `#ref` variable on a DOM node in the template will be
* determined by the type of `document.createElement` for the given DOM node type. If set to
* `false`, the type of `ref` for DOM nodes will be `any`.
*/
checkTypeOfDomReferences: boolean;
/**
* Whether to infer the type of local references.
*
* If this is `true`, the type of a `#ref` variable that points to a directive or `TemplateRef` in
* the template will be inferred correctly. If set to `false`, the type of `ref` for will be
* `any`.
*/
checkTypeOfNonDomReferences: boolean;
/**
* Whether to include type information from pipes in the type-checking operation.
*
* If this is `true`, then the pipe's type signature for `transform()` will be used to check the
* usage of the pipe. If this is `false`, then the result of applying a pipe will be `any`, and
* the types of the pipe's value and arguments will not be matched against the `transform()`
* method.
*/
checkTypeOfPipes: boolean;
/**
* Whether to narrow the types of template contexts.
*/
applyTemplateContextGuards: boolean;
/**
* Whether to use a strict type for null-safe navigation operations.
*
* If this is `false`, then the return type of `a?.b` or `a?()` will be `any`. If set to `true`,
* then the return type of `a?.b` for example will be the same as the type of the ternary
* expression `a != null ? a.b : a`.
*/
strictSafeNavigationTypes: boolean;
/**
* Whether to descend into template bodies and check any bindings there.
*/
checkTemplateBodies: boolean;
/**
* Whether to check resolvable queries.
*
* This is currently an unsupported feature.
*/
checkQueries: false;
}
export type TemplateSourceMapping =
DirectTemplateSourceMapping | IndirectTemplateSourceMapping | ExternalTemplateSourceMapping;
/**
* A mapping to an inline template in a TS file.
*
* `ParseSourceSpan`s for this template should be accurate for direct reporting in a TS error
* message.
*/
export interface DirectTemplateSourceMapping {
type: 'direct';
node: ts.StringLiteral|ts.NoSubstitutionTemplateLiteral;
}
/**
* A mapping to a template which is still in a TS file, but where the node positions in any
* `ParseSourceSpan`s are not accurate for one reason or another.
*
* This can occur if the template expression was interpolated in a way where the compiler could not
* construct a contiguous mapping for the template string. The `node` refers to the `template`
* expression.
*/
export interface IndirectTemplateSourceMapping {
type: 'indirect';
componentClass: ClassDeclaration;
node: ts.Expression;
template: string;
}
/**
* A mapping to a template declared in an external HTML file, where node positions in
* `ParseSourceSpan`s represent accurate offsets into the external file.
*
* In this case, the given `node` refers to the `templateUrl` expression.
*/
export interface ExternalTemplateSourceMapping {
type: 'external';
componentClass: ClassDeclaration;
node: ts.Expression;
template: string;
templateUrl: string;
}