有没有办法分解功能参数并保留对该参数的命名引用?

时间:2019-05-29 03:27:02

标签: javascript reactjs typescript destructuring

在反应无状态功能组件时,我们通常会这样写:

export function MyCompoment({
    title, 
    foo, 
    bar
}) {
    return <div> title: {title}, ...</div>
}

我们立即将props对象分解为它的变量。

现在,我正在使用Material-UI makeStyles钩子,并且还在使用TypeScript,并且当前使用它的方式如下所示。

const useStyles = makeStyles((theme : Theme ) =>({
     root: ({foo} : MyComponentProps) => ({
         content: foo
     })
}); 

interface MyComponentProps  {
    title: string; 
    foo: string; 
    bar: string; 
}
export function MyCompoment({
    title, 
    foo, 
    bar
} : MyComponentProps) {
    const classes = useStyles({
        title,
        foo, 
        bar
    }); 
    return <div> title: {title}, ...</div>
}

您会看到问题-我必须重复props变量名才能传递到类中。

我想避免这种情况的最好方法是这样写:

export function MyCompoment(props: MyComponentProps) {
    const {
       title, 
       foo, 
       bar
    }  = props; 
    const classes = useStyles(props); 
    return <div> title: {title}, ...</div>
}

但是那比我想要的要混乱一些。

我想知道是否可以做类似的事情:

export function MyCompoment({
       title, 
       foo, 
       bar
    }  = props : MyComponentProps) {

    const classes = useStyles(props); 
    return <div> title: {title}, ...</div>
}

我知道,很挑剔。

3 个答案:

答案 0 :(得分:1)

不(主要)


摘自语法:

很难证明是否定的,所以我不得不去语法。

据我所知,Typescript不能提供javascript无法提供的任何额外的解构能力,所以我只用javascript来回答。

在ES6语法中,无法破坏单个功能参数并在一个参数中的参数列表中为其指定名称。

如果您查看FormalParameter的{​​{3}}(这是参数列表中的内容之一),则会发现它只能是BindingElement,它可以是SingleNameBindingBindingPattern-不能同时使用。绑定模式只能进行解构,而单个名称绑定只能分配给一个值,因此无法同时进行这两种操作。

(请注意,我链接的语法只是某人放在github上的要点。我不认为有人会在github上发布误导性的ES6语法,但是如果您对此表示怀疑,可以随时检查不太方便的官方语法。)

我可能错过了其他一些疯狂的方式来做到这一点,但我从未见过,并且会感到非常惊讶。


如果您真的想...

您也是“您可以想到的最佳方式”也是我可以想到的最佳方式。你应该那样做。

但是,我不喜欢回答“否”,因此,如果您真的想在参数列表中获得全部信息,则可以执行一些不愉快的事情。如果您这样做:

function assignAndDestructure(props, { foo, bar } = props) {
    // props, foo, and bar will all be assigned
}

哪种类型符合您的标准。但是,它创建了一个可选的第二个参数,调用者可以滥用该参数来破坏您的销毁。您可以通过将其分配给Typescript中没有该参数的类型来隐藏它,但这仍然存在风险。


总而言之,没有很好的方法,但是有一个不好的方法。提到您提到的“您能想到的最好的东西”。

答案 1 :(得分:0)

  

有没有办法分解一个函数参数,并保留对该参数的命名引用?

不。您将需要做两步,因为需要将道具作为单个参数,然后将其分解。

答案 2 :(得分:0)

我不明白为什么有人想出这个答案...... 您始终可以引用 arguments 中的参数。

function _test({ a, b }){ 
  var arg = arguments[0];
  console.log("a=",a,"b=",b,"arg=",arg);
}

当测试产生此输出时:

_test({ a:23, b:"asd", c:"$" })
// a= 23 b= asd arg= { a: 23, b: 'asd', c: '$' }

在你的情况下可以这样做。

export function MyCompoment({
       title, 
       foo, 
       bar
    }) {
    const props = arguments[0];
    const classes = useStyles(props); 
    return <div> title: {title}, ...</div>
}