在反应无状态功能组件时,我们通常会这样写:
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>
}
我知道,很挑剔。
答案 0 :(得分:1)
不(主要)
很难证明是否定的,所以我不得不去语法。
据我所知,Typescript不能提供javascript无法提供的任何额外的解构能力,所以我只用javascript来回答。
在ES6语法中,无法破坏单个功能参数并在一个参数中的参数列表中为其指定名称。
如果您查看FormalParameter
的{{3}}(这是参数列表中的内容之一),则会发现它只能是BindingElement
,它可以是SingleNameBinding
或BindingPattern
-不能同时使用。绑定模式只能进行解构,而单个名称绑定只能分配给一个值,因此无法同时进行这两种操作。
(请注意,我链接的语法只是某人放在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>
}