Idea: treat explicit `undefined` variables the same as "not defined" variables
First, some terminology:
- an explicit
undefinedvariable is one assigned toundefinedin the JavaScript and passed into a template as context; - an implicit
undefinedvariable is a "missing" variable—i.e., one that has not been passed in as context (or declared withset).
TLDR: I suggest that we treat explicit undefined variables exactly the same way that we treat implicit undefined variables.
As far as I can tell, implicit undefined variables in Twing are treated just like "missing" variables are in TwigPHP. Depending on whether strict_variables is enabled, you'll get either null or a "does not exist" runtime error if you try to use one. This is exactly as it should be, as described in the Twig docs: https://twig.symfony.com/doc/3.x/api.html#environment-options
Explicit undefined variables, however, have no direct analogue in TwigPHP, which means that how they should be handled is a matter of judgment. (That's why I've marked this as a discussion, and not a bug.)
Currently, explicit undefined variables aren't treated like implicit undefined variables in Twing. It looks to me like they're simply not treated in any special way at all.
For example, with the strict_variables option enabled, a Twig file with no context that reads {{ foo }} will throw a "does not exist" runtime error, while the same Twig file with a context of { foo: undefined } will not result in an error and will instead print nothing. Similarly, if strict_variables is disabled, then an implicit undefined variable is coerced to null before getting processed by filters/functions/tests/etc., whereas an explicit undefined value reaches them as undefined.
I think that it would be better to treat explicit undefined values the same way we treat implicit undefined variables. Here is my reasoning:
As things stand, passing in explicit undefined variables can result in unexpected behavior, and the developer should therefore always either use null instead or omit the variable/property altogether to be safe. However:
- Many JavaScript developers consider it best practice to never use
nullwhen explicitly declaring that a variable or property is "empty," and instead to always useundefined. - If you're creating a JavaScript object literal, the inline syntax to conditionally include a property (
{ ...(condition ? { key: value } : {}) }) is awkward and unreadable compared to the inline syntax for conditionally assigning itundefined/null({ key: condition ? value : undefined }). - In TypeScript, optional properties like
prop?: stringcannot benullbut can beundefined(unlessexactOptionalPropertyTypesis enabled).
For these reasons, it's inconvenient and unnatural for the JavaScript or TypeScript developer to avoid undefined in favor of null and omitted variables/properties. Treating explicit undefined like implicit undefined would prevent some unexpected behavior and allow developers to use undefined without worry.