` and inserts that view in a [view container](api/core/ViewContainerRef "API: ViewContainerRef") adjacent to the directive's original `` host element.
[`TemplateRef`](api/core/TemplateRef "API: TemplateRef") helps you get to the `` contents and [`ViewContainerRef`](api/core/ViewContainerRef "API: ViewContainerRef") accesses the view container.
1. Add an `appUnless` `@Input()` property with a setter.
Angular sets the `appUnless` property whenever the value of the condition changes.
* If the condition is falsy and Angular hasn't created the view previously, the setter causes the view container to create the embedded view from the template
* If the condition is truthy and the view is currently displayed, the setter clears the container, which disposes of the view
The complete directive is as follows:
### Testing the directive
In this section, you'll update your application to test the `UnlessDirective`.
1. Add a `condition` set to `false` in the `AppComponent`.
1. Update the template to use the directive.
Here, `*appUnless` is on two `` tags with opposite `condition` values, one `true` and one `false`.
The asterisk is shorthand that marks `appUnless` as a structural directive.
When the `condition` is falsy, the top \(A\) paragraph appears and the bottom \(B\) paragraph disappears.
When the `condition` is truthy, the top \(A\) paragraph disappears and the bottom (B) paragraph appears.
1. To change and display the value of `condition` in the browser, add markup that displays the status and a button.
To verify that the directive works, click the button to change the value of `condition`.
## Structural directive syntax reference
When you write your own structural directives, use the following syntax:
*:prefix="( :let | :expression ) (';' | ',')? ( :let | :as | :keyExp )*"
The following tables describe each portion of the structural directive grammar:
as = :export "as" :local ";"?
keyExp = :key ":"? :expression ("as" :local)? ";"?
let = "let" :local "=" :export ";"?
| Keyword | Details |
|:--- |:--- |
| `prefix` | HTML attribute key |
| `key` | HTML attribute key |
| `local` | Local variable name used in the template |
| `export` | Value exported by the directive under a given name |
| `expression` | Standard Angular expression |
### How Angular translates shorthand
Angular translates structural directive shorthand into the normal binding syntax as follows:
| Shorthand | Translation |
|:--- |:--- |
| `prefix` and naked `expression` | [prefix]="expression" |
| `keyExp` | [prefixKey] "expression" (let-prefixKey="export") **NOTE**:
The `prefix` is added to the `key`
|
| `let` | let-local="export" |
### Shorthand examples
The following table provides shorthand examples:
| Shorthand | How Angular interprets the syntax |
|:--- |:--- |
| *ngFor="let item of [1,2,3]" | <ng-template ngFor 
 let-item 
 [ngForOf]="[1,2,3]"> |
| *ngFor="let item of [1,2,3] as items; 
 trackBy: myTrack; index as i" | <ng-template ngFor 
 let-item 
 [ngForOf]="[1,2,3]" 
 let-items="ngForOf" 
 [ngForTrackBy]="myTrack" 
 let-i="index"> |
| *ngIf="exp" | <ng-template [ngIf]="exp"> |
| *ngIf="exp as value" | <ng-template [ngIf]="exp" 
 let-value="ngIf"> |
## Improving template type checking for custom directives
You can improve template type checking for custom directives by adding template guard properties to your directive definition.
These properties help the Angular template type checker find mistakes in the template at compile time, which can avoid runtime errors.
These properties are as follows:
* A property `ngTemplateGuard_(someInputProperty)` lets you specify a more accurate type for an input expression within the template
* The `ngTemplateContextGuard` static property declares the type of the template context
This section provides examples of both kinds of type-guard property.
For more information, see [Template type checking](guide/template-typecheck "Template type-checking guide").
### Making in-template type requirements more specific with template guards
A structural directive in a template controls whether that template is rendered at run time, based on its input expression.
To help the compiler catch template type errors, you should specify as closely as possible the required type of a directive's input expression when it occurs inside the template.
A type guard function narrows the expected type of an input expression to a subset of types that might be passed to the directive within the template at run time.
You can provide such a function to help the type-checker infer the proper type for the expression at compile time.
For example, the `NgIf` implementation uses type-narrowing to ensure that the template is only instantiated if the input expression to `*ngIf` is truthy.
To provide the specific type requirement, the `NgIf` directive defines a [static property `ngTemplateGuard_ngIf: 'binding'`](api/common/NgIf#static-properties).
The `binding` value is a special case for a common kind of type-narrowing where the input expression is evaluated in order to satisfy the type requirement.
To provide a more specific type for an input expression to a directive within the template, add an `ngTemplateGuard_xx` property to the directive, where the suffix to the static property name, `xx`, is the `@Input()` field name.
The value of the property can be either a general type-narrowing function based on its return type, or the string `"binding"`, as in the case of `NgIf`.
For example, consider the following structural directive that takes the result of a template expression as an input:
In this example, the `LoadingState` type permits either of two states, `Loaded` or `Loading`.
The expression used as the directive's `state` input (aliased as `appIfLoaded`) is of the umbrella type `LoadingState`, as it's unknown what the loading state is at that point.
The `IfLoadedDirective` definition declares the static field `ngTemplateGuard_appIfLoaded`, which expresses the narrowing behavior.
Within the `AppComponent` template, the `*appIfLoaded` structural directive should render this template only when `state` is actually `Loaded`.
The type guard lets the type checker infer that the acceptable type of `state` within the template is a `Loaded`, and further infer that `T` must be an instance of `Hero`.
### Typing the directive's context
If your structural directive provides a context to the instantiated template, you can properly type it inside the template by providing a static `ngTemplateContextGuard` function.
The following snippet shows an example of such a function.
@reviewed 2022-02-28