No (mostly)
From the grammar:
It's hard to prove a negative, so I had to go to the grammar.
Typescript, as far as I'm aware, does not provide any extra destructuring power that javascript does not, so I'll just answer this for javascript.
In the ES6 grammar, there's no way for a single function parameter to be both destructed and given a name in the parameter list, in one parameter.
If you look at the ES6 grammar for FormalParameter, which is one of the things in an argument list, you'll find it can only be a BindingElement, which is either a SingleNameBinding or a BindingPattern โ not both. Binding patterns can only do destructuring and single name bindings can only assign to one value, so there's no way to do both.
(Note the grammar I linked is just a gist someone put on github. I don't think someone would post a misleading ES6 grammar on github, but if you're skeptical you can always check the less convenient official grammar.)
It's possible there's some other wild way to do this that I missed, but I've never seen it before and would be very surprised.
If you really want to...
You're "best way you can think of" is the best way I can think of too. You should do that.
I don't like answering "no", though, so if you really want to get it all in the parameter list, you can do something unpleasant instead. If you do:
function assignAndDestructure(props, { foo, bar } = props) {
// props, foo, and bar will all be assigned
}
which kind of fits your criteria. However, it creates an optional second parameter the caller can abuse to mess up your destructuring. You can hide it by assigning it to a type that doesn't have that parameter in Typescript, but it's still risky.
In summary, there's no good way to do it, but there is a bad way. Go with your mentioned "best you can think of."
I don't understand why anybody came up with this answer...
You always have a reference to the parameter in arguments.
function _test({ a, b }){
var arg = arguments[0];
console.log("a=",a,"b=",b,"arg=",arg);
}
When tested produces this output:
_test({ a:23, b:"asd", c:"$" })
// a= 23 b= asd arg= { a: 23, b: 'asd', c: '$' }
In your case it could be done this way.
export function MyCompoment({
title,
foo,
bar
}) {
const props = arguments[0];
const classes = useStyles(props);
return <div> title: {title}, ...</div>
}
const func = (a, b, {c: {d}}) => {console.dir(d)}
func(null, null, {c: {d: document.location}});
Run code snippetEdit code snippet Hide Results Copy to answer Expand
This function has to be called with object that has key c, which has object with key d as value:
func(a, b, {c: {d: document.location }})
console.dir() takes any JS object as parameter.
{ c: {d}} is a syntax called object destructuring and its purpose in this context is unpacking fields from objects passed as function parameter.
{d} is shorter syntax for object with key d and value of variable d ({d: d}).
To unpack variable d from object under key c, that object have to have that key initialized! But when you further destructurize the object passed as argument, you don't have that object as a variable in the scope.
In example you have provided, you will not be able to access object c, as it has been destructurized and only object d is available. Either you have mistake in your code or you need something like Anurat Chapanond has posted.
Here is one example.
const func = (a, b, {c: {d}}) => {console.dir(c)},
c = { d: 'hello' }
func(1, 2, { c })
I define c as an object with a property d which is a string 'hello'.
when func is called, the third parameter I pass to the function is an object with a property c.
{ c } is a shorthand for { c: c }