closure-builder
Version:
Simple Closure, Soy and JavaScript Build system
61 lines (49 loc) • 2.58 kB
Markdown
In Soy it is common to have optional
[](../reference/templates.md
types](../reference/types
you from accidentally dereferencing potentially null values and it provides
additional information to callers. However, for these same reasons they can be
difficult to work with. This page shows a few strategies for dealling with
`null` in your templates.
[]
When a template contains an optional parameter (`@param?`), if the compiler can
prove the parameter cannot be null it will change the expression type to be
non-optional. For example:
```soy
{template .main}
/** Optional parameter of type (foo.bar.Person|null). */
{@param? person: foo.bar.Person}
{if $person}
// Within this if-block, person can never be null, so the type
// is now ‘map’, not ‘(map|null)’
{$person.name}
{else}
// Compile-time error: $person can only be null at this point.
{$person.name}
{/if}
{/template}
```
This type narrowing feature is triggered by the various control flow mechanisms:
* [if statements](../reference/control-flow
* [and/or operators](../reference/expressions
* [null coalescing
operator](../reference/expressions
* [ternary operator](../reference/expressions
When the predicate of the conditional is a comparison with `null` the compiler
is able to narrow the type on each side of the branch. This includes implicit
comparisons as well as explicit ones using the
[`isNull`](../reference/functions
[`isNonnull`](../reference/functions
For example consider these expressions, `$foo ? A : B`, `$foo != null ? A : B`,
`isNonnull($foo) ? A : B`. In each example, the variable `$foo` is compared with
`null` either implicitly or explicitly, so within the `A` branch we know that
all references to `$foo` are guaranteed to be non-null and so the type is
modified to reflect that. Furthermore within the `B` branch we know that `$foo`
is `null` or at least is `falsy`.
The [`checkNotNull`](../reference/functions
return its parameter or throw an unspecified exception if the provided value is
`null`. Additionally the type checker understands this behavior and so this can
be used a cast operator to turn nullable types into non-nullable types.