Skip to content

Feature request: Support renaming in object destructuring #4747

@Swahjak

Description

@Swahjak

Summary

Twig 3.23 added excellent destructuring support. Object destructuring {a, b} = obj works great for extracting properties with their original names. However, there's no way to rename variables during destructuring, which limits its usefulness when you need to call the same function multiple times.

Current Behavior

Object destructuring only works with matching names:

{# Works - extracts obj.name and obj.email into variables with same names #}
{% do {name, email} = user %}

The {key: value} syntax does NOT rename - the key is ignored:

{% do {product: data} = obj %}
{# Result: data = obj.data (the key "product" is completely ignored) #}
{# The variable "product" is never set #}

This differs from JavaScript where {data: product} means "extract data and assign to product":

const { data: product } = obj;  // product = obj.data

The Problem

When calling a function multiple times, you need different variable names but can't rename:

{# This doesn't work - second call overwrites first #}
{% do {data, error} = view('ProductViewModel') %}
{% do {data, error} = view('StockViewModel') %}  {# overwrites! #}

{# Forced to use intermediate variables #}
{% do {data, error} = view('ProductViewModel') %}
{% set product = data %}
{% set productError = error %}

{% do {data, error} = view('StockViewModel') %}
{% set stock = data %}
{% set stockError = error %}

Desired Behavior

Support JavaScript-style renaming where the key is the property to extract and the value is the variable to assign to:

{% do {data: product, error: productError} = view('ProductViewModel') %}
{% do {data: stock, error: stockError} = view('StockViewModel') %}

{# product = result.data, productError = result.error #}
{# stock = result.data, stockError = result.error #}

Current Workaround

Using sequence destructuring with indexed arrays, which allows free variable naming but loses the self-documenting property names:

{% do [product, productError] = view('ProductViewModel') %}
{% do [stock, stockError] = view('StockViewModel') %}

This works but requires changing return types from associative to indexed arrays, and the meaning of positions isn't self-evident.

Technical Notes

Looking at ObjectDestructuringSetBinary, the current implementation only uses $pair['value'] (the variable) and ignores $pair['key']:

foreach ($left->getKeyValuePairs() as $pair) {
    // Only the value is used - key is ignored
    $this->properties[] = $pair['value']->getAttribute('name');
}

To support renaming, it would need to:

  1. Use $pair['key'] as the property name to extract from the object
  2. Use $pair['value'] as the variable name to assign to

Thank you for considering this feature!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions