UNPKG

closure-builder

Version:

Simple Closure, Soy and JavaScript Build system

61 lines (49 loc) 2.58 kB
# Dealing with nullable types In Soy it is common to have optional [parameters](../reference/templates.md#param) and other [nullable types](../reference/types#null). This is useful since the compiler will prevent 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. [TOC] ## Static type narrowing in conditional blocks 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#if) * [and/or operators](../reference/expressions#logical-operators) * [null coalescing operator](../reference/expressions#null-coalescing-operator) * [ternary operator](../reference/expressions#ternary) 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#isNull) and [`isNonnull`](../reference/functions#isNonnull) 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`. ## `checkNotNull` function The [`checkNotNull`](../reference/functions#checkNotNull) function will either 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.