# Destructuring with Alias Binding

**URL:** <https://es.discourse.group/t/destructuring-with-alias-binding/2370>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [May 16, 2025, 10:32pm UTC](https://es.discourse.group/t/destructuring-with-alias-binding/2370 "2025-05-16T22:32:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![EzioMercer](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/eziomercer/32/2460_2.png) [@EzioMercer](https://es.discourse.group/u/EzioMercer)\
**Post date:** [May 16, 2025, 10:32pm UTC](https://es.discourse.group/t/destructuring-with-alias-binding/2370/1 "2025-05-16T22:32:34Z")

</div>

It is my first time here, so please be patient with me 👋

I'm aware of:

- [GitHub - zkat/proposal-as-patterns: `as` destructuring patterns](https://github.com/zkat/proposal-as-patterns)

- [GitHub - tc39/proposal-pattern-matching: Pattern matching syntax for ECMAScript](https://github.com/tc39/proposal-pattern-matching)

- For me the first one is very specific, there can be better solutions for the idea

- The second one requires very big changes and may be IMHO 100 times more work than my proposal and still doesn't provide any easy mechanism for my idea

The main idea is to have an easy syntax for destructured parts

The below text is the copypasta from my GitHub repository. To see most recent version of proposal please follow [this link](https://github.com/EzioMercer/destructuring-with-alias-binding)

# Destructuring with Alias Binding

# Motivations

This proposal suggests a new syntax which will be useful shorthand for saving destructed variables in object  
immediately without the need to repeat them to create a new object

In my practice, it is ubiquitous to write something like this:

```js
const foo = (config) => {
    const _config = {
        ...config,
        x: Number(config.x)
    }
    
    console.log(_config);
    /*
    Output:
    {
        ...some properties,
        x: number
    }
    */
}

```

And here is the problem for me because `config` can be an object with extra keys which I don't want to have inside the  
function.  
So I have to rewrite it like this:

```js
const foo = ({
    prop1,
    prop2,
    x
}) => {
    const _config = {
        prop1,
        prop2,
        x: Number(x)
    }
    
    console.log(_config);
    /*
    Output:
    {
        prop1: any,
        prop2: any,
        x: number
    }
    */
}

```

And now the problem is that I have to write the exact same things twice.  
So my proposal is to let rewrite the above code in that way:

```js
const foo = ({ prop1, prop2, x } as config) => {
    const _config = {
        ...config,
        x: Number(x)
    }
    
    console.log(_config);
    /*
    Output:
    {
        prop1: any,
        prop2: any,
        x: number
    }
    */
}

```

In that way I can access the `x` explicitly writing it or get it from `config` like this `config.x` or `config['x']`

# Possible solutions without this proposal

### Rewrite with `...args`

```js
const foo = (...args) => {
    const _config = {
        ...args[0],
        x: Number(x)
    }
    
    console.log(_config);
    /*
    Output:
    {
        ...some properties,
        x: number
    }
    */
}

```

But the problem with this approach is that now I don't have control of which properties will be passed into the first  
argument.  
With this proposal, at least I can easily omit the unnecessary properties which can cause bugs or unexpected  
results

### Rewrite arrow functions into classic functions

```js
function foo({
    prop1,
    prop2,
    x
}) {
    const _config = {
        ...arguments[0],
        x: Number(x)
    }
    
    console.log(_config);
    /*
    Output:
    {
        prop1: any,
        prop2: any,
        x: number
    }
    */
}

```

This is the closest approach because now I can access properties both individually and by the alias using `arguments`

# Features

### Granular control of the passed object

Despite the approach using the `arguments` which is great for first level aliases it is still impossible to control  
second or more levels of object.  
But with this proposal we can control like this:

```js
const foo = ({
    prop1,
    prop2,
    prop3: {
        prop4,
        prop5
    } as innerConfig,
    prop6: {
        prop7: {
            prop8,
            prop9
        } as innerInnerInnerConfig
    } as innerInnerConfig,
    x
} as config) => {
    const _config = {
        ...config,
        x: Number(x)
    }
    
    console.log(_config);
    /*
    {
        prop1: any,
        prop2: any,
        prop3: {
            prop4: any,
            prop5: any
        },
        prop6: {
            prop7: {
                prop8: any,
                prop9: any
            }
        },
        x: number
    }
    */
    
    console.log(innerConfig);
    /*
    {
        prop4: any,
        prop5: any
    }
    */
    
    console.log(innerInnerConfig);
    /*
    {
        prop7: {
            prop8: any,
            prop9: any
        }
    }
    */
    
    console.log(innerInnerInnerConfig);
    /*
    {
        prop8: any,
        prop9: any
    }
    */
}

```

# Similar possibilities in other languages:

### F# (`as` keyword)

```javascript
let (var1, var2) as tuple = (1, 2)

printfn "var1: %d var2: %d tuple: %A" var1 var2 tuple // Output: var1: 1 var2: 2 tuple: 1,2

```

### Haskell (`@` symbol)

```haskell
processTuple :: (Int, Int) -> String
processTuple t@(a, b) = "First: " ++ show a ++ ", Second: " ++ show b ++ ", Original Tuple: " ++ show t

main :: IO ()
main = do
  putStrLn $ processTuple (1, 2) -- Output: First: 1, Second: 2, Original Tuple: (1,2)

```

```haskell
data Person = Person { name :: String, age :: Int } deriving Show

processPerson :: Person -> String
processPerson p@(Person n a) = "Name: " ++ n ++ ", Age: " ++ show a ++ ", Original Person: " ++ show p

main :: IO ()
main = do
  let alice = Person { name = "Alice", age = 30 }
  putStrLn $ processPerson alice -- Output: Name: Alice, Age: 30, Original Person: Person {name = "Alice", age = 30}

```

### Erlang (`=` symbol)

```erlang
process_tuple(T={A, B}) ->
    io:format("First: ~p, Second: ~p, Original Tuple: ~p~n", [A, B, T]). % Output: First: 1, Second: 2, Original Tuple: {1,2}

process_person(P=#{name := N, age := Ag}) ->
    io:format("Name: ~s, Age: ~p, Original Person: ~p~n", [N, Ag, P]). % Output: Name: Alice, Age: 30, Original Person: #{age => 30,name => "Alice"}

main(_) ->
    process_tuple({1, 2}),
    process_person(#{name => "Alice", age => 30}).

```

# Notes

I suggest `as` keyword because it is the first word which I came up with.  
As we can see, other languages use different syntax for the same thing.  
My suggestion doesn't require the `as` keyword as the solution.  
It can be:

- keyword: `in`, `into`, `use`, `save`, `template`, `like` etc.
- symbol/operator: `=>`, `>>`, `->`, `<=`, `<<`, `<-`, `@`, `#`, `$`, `~`, `~>`, `<~` etc.

The keyword or symbol or operator also is not required to come after the destructing syntax

### P.S.

Please don't hesitate to:

- give a star ☆
- share your ideas
- share this proposal with others
- provide more useful examples
- provide possible problems with this proposal
- suggest text improvements
- help with `emu` file

You can browse the [ecmarkup output](https://EzioMercer.github.io/naming-destructed-variables/)  
or browse the [source](https://github.com/EzioMercer/naming-destructed-variables/blob/main/spec.emu)

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [May 17, 2025, 6:53am UTC](https://es.discourse.group/t/destructuring-with-alias-binding/2370/2 "2025-05-17T06:53:11Z")

</div>

If I understand correctly this also sounds like: [Object.{pick,omit}](https://es.discourse.group/t/object-pick-omit/515)

---

<div class="post-metadata">

**Author:** ![EzioMercer](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/eziomercer/32/2460_2.png) [@EzioMercer](https://es.discourse.group/u/EzioMercer)\
**Post date:** [May 17, 2025, 4:45pm UTC](https://es.discourse.group/t/destructuring-with-alias-binding/2370/4 "2025-05-17T16:45:20Z")

</div>

To be honest I don't think so. You are absolutely right that I can achieve this using the proposal which you mentioned but it is not the for same purpose.

With object destructing in function arguments level I can guarantee the shape of the alias which I will use but with `Object.{pick, omit}` I have to do it by myself

If you saw the `Possible solutions without this proposal` section then you could notice that the same thing I can do now with classic function and `arguments`. But it will work good only for one level of depth

Also if I understand correctly the mentioned proposal then it also work for one level of depth what means that for `nth` level of depth I had to do a lot of work or create an util function

The `Object.{pick, omit}` proposal is great by itself but for me the main purpose of these two proposals are very different

---

<div class="post-metadata">

**Author:** ![EzioMercer](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/eziomercer/32/2460_2.png) [@EzioMercer](https://es.discourse.group/u/EzioMercer)\
**Post date:** [May 19, 2025, 7:28pm UTC](https://es.discourse.group/t/destructuring-with-alias-binding/2370/5 "2025-05-19T19:28:07Z")

</div>

Updates:

- Major changes:
  - Added improvements (grouping syntax)

- Some minor changes and text improvements

Please see updated version on GitHub
