Есть ли способ как деструктурировать параметр функции, так и сохранить именованную ссылку на параметр? - PullRequest
4 голосов
/ 29 мая 2019

В функциональных компонентах без учета состояния мы обычно пишем что-то вроде этого:

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>
}

Довольно разборчиво, я знаю, просто интересно.

Ответы [ 2 ]

1 голос
/ 29 мая 2019

Нет (в основном)


Из грамматики:

Трудно доказать отрицание, поэтому мне пришлось перейти к грамматике.

Насколько мне известно, Typescript не предоставляет никакой дополнительной деструктурирующей силы, чем javascript, поэтому я просто отвечу на этот вопрос для javascript.

В грамматике ES6 невозможно, чтобы один параметр функции был уничтожен и получил имя в списке параметров в одном параметре.

Если вы посмотрите на ES6 грамматику для FormalParameter, которая является одной из вещей в списке аргументов, вы обнаружите, что это может быть только BindingElement, который является либо SingleNameBinding или BindingPattern - не оба. Шаблоны привязки могут выполнять только деструктурирование, а привязки к одному имени могут назначаться только одному значению, поэтому нет возможности сделать и то, и другое.

(Обратите внимание, что грамматика, которую я связал, - это просто суть, которую кто-то написал на github. Не думаю, что кто-то опубликует вводящую в заблуждение грамматику ES6 на github, но если вы настроены скептически, вы всегда можете проверить менее удобную официальную грамматику.)

Возможно, есть какой-то другой дикий способ сделать это, что я пропустил, но я никогда не видел этого раньше и был бы очень удивлен.


Если вы действительно хотите ...

Ты "лучший способ думать" - это тоже лучший способ, о котором я могу думать. Ты должен это сделать.

Мне не нравится отвечать «нет», поэтому, если вы действительно хотите получить все это в списке параметров, вы можете вместо этого сделать что-то неприятное. Если вы делаете:

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

какой вид соответствует вашим критериям. Тем не менее, он создает необязательный второй параметр, который вызывающий может использовать, чтобы испортить вашу деструктуризацию. Вы можете скрыть это, назначив его типу, у которого нет этого параметра в Typescript, но это все еще рискованно.


Таким образом, нет хорошего способа сделать это, но есть плохой способ. Пойдите со своим упомянутым "лучшим, о чем Вы можете думать."

0 голосов
/ 29 мая 2019

Есть ли способ как деструктурировать параметр функции, так и сохранить именованную ссылку на параметр?

Нет. Вам нужно будет сделать это в два этапа, так как вы берете реквизиты в качестве одного аргумента, а затем деструктурируете их позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...