Pull to refresh

Comments 29

Но теперь ESLint ругается на нарушение правила no-use-before-define. А менять конфигурацию ESLint в CRA нельзя.

А почему нельзя просто перенести определение Props в начало файла?

WebStorm сворачивает импорты. В результате, когда открываю файл, то первым делом вижу реализацию компонента. А типы по переходу в конец файла [CTRL]+[END]. Привычка.

Неправильная привычка у вас :)
Props это как входные параметры функции -> идут первыми.
Компонент это возвращаемый результат -> идёт последним

Неправильная привычка у вас

Спорно. Помнится, ещё в Delphi можно было отдельно объявить тип для использования, и описывать его где-нибудь ниже по коду. Ностальгия. Я применяю деструктуризацию для props, т.е. имена аргументов видно сразу. А разглядывать их типы не особо интересно — информационный шум.

Не обязательно. Обычно react-redux'овский mapStateToProps для компонента идёт вместе с экспортом, соответственно рядом с ними же стоить размещать типы параметров. Так что я считаю логичной такую структуру:


// Компонент
class SomeComponent extends Component {
    // ...
}

// Экспорт
const mapStateToProps = state => ({
    prop: state.section.prop
})

SomeComponent.propTypes = {
    prop: React.PropTypes.string
}

export default connect(mapStateToProps)(SomeComponent)

А вообще синтаксис flow позволяет такое:


class SomeComponent extends Component {
    props: {
        prop1: string,
        prop2: number,
    }

    constructor(props) {
        super(props)
        // ...
    }
}
А вообще синтаксис flow позволяет такое

Это сделано для тех, кто привык использовать static propTypes, очевидно. Но засорять тельце компонента — как-то совсем, на мой вкус. И не добиться единообразия с функциональными компонентами.

Перекраивать create-react-app на кастомный конфиг только из-за привычки искать определения типов в конце?
Мне кажется, это слишком радикальное решение.


И во-вторых, no-use-before-define включен тоже не просто так, чтобы вам мешать. Код читается сверху вниз, если нам нужно посмотреть определение какой-то переменной, то его нужно искать выше по тексту. И определение типов тут не исключение.

Перекраивать create-react-app на кастомный конфиг только из-за...

Не только, аппетит приходит во время еды: styled-jsx, module-resolver, tcomb.


no-use-before-define включен тоже не просто так, чтобы вам мешать

Я сразу предупредил, что "хочется странного" — это послание специально для вас.

Babel мне позволяет извращаться, а вы обратно запрещаете. Ну и кого мне слушаться? :)

Create-react-app — это не Babel, и конфигурации не имеет (react-app-rewired не в счет, потому что это неофициальное дополнение).


И я бы не стал отклоняться от его настроек. Сила create-react-app — в единообразии. Все проекты имеют одинаковый набор технологий и используют одинаковый стиль кода. Очень легко вникать в проект, даже если начинал его не я.

Babel живет внутри CRA. И Babel из коробки это позволяет, конфигурировать его не надо.

Признаю, это была сомнительная самодеятельность. WebStorm и VSCode позволяют сворачивать блоки. К сожалению WebStorm не запоминает состояние (Folding), в отличии от VSCode.

flow-typed.

И добавить отдельную директорию для типов. Когда типы разростаются, то файлы получаются очень большие и не информативные. а вот intellisense так же парсит
   flow-typed
    - npm
    - types
      - TableRowsType.js
      - AppType.js

Вот тут я сомневаюсь. Компоненты стремятся почковаться до атомарного состояния. Чем меньше — тем лучше. Это оправдано, хотя стучать по клаве утомляет. Отсюда и типы уменьшаются. А вот переключать контекст внимания между файлов — только раздражает. Я вкрячил CSS в компоненты посредством styled-jsx — ужасно доволен, например.


Конечно, бывают исключения. Когда один тип используется в нескольких файлах, и недоступен иначе из-за циклического импорта компонентов.


https://github.com/comerc/yobr/blob/master/src/components/Post/Post.js

Это конспект части доклада

Так вот почему текст так похож на стенограмму, с трудом осилил. А многое просто не понял.




Ни когда не слышал про flow поэтому следующие вопросы такие нубские:


И тут на помощь приходит восхитительнейший плагин… tcomb

Это плагин от flow, от babel или от IDE?
Какими IDE поддерживается flow?

Это плагин от flow, от babel или от IDE?

babel-plugin-tcomb — транспайлит код с применением tcomb.


Какими IDE поддерживается flow?

Nuclide точно поддерживает. Очевидно, что Visual Studio не отстает, но этого я не пробовал.


Настройка WebStorm:


Какую версию TypeScript вы пробовали?
Во второй гораздо сильнее вывод типов и strictNullChecks
function b(c: number | undefined) {
    c.toExponential(); // Error: Object is possibly undefined.
    if (typeof (c) !== "undefined") {
        c.toExponential(); // No error
    }
}
function d(c: number) {
    // CODE
 }
b(1);
d(undefined); // Error: Argument of type 'undefined' is not assignable to parameter of type 'number'.


Также очень вкусный keyof
Какую версию TypeScript вы пробовали?

Мопед не мой. Это вопрос к автору доклада.

Flow классная штука, flow+tcomb — наверное, ещё круче.


Но всё-таки печалит тот факт, что некоторые вещи он не распознаёт корректно :-(
Вот примеры кода, на который ругается flow, но которые допускаются typescript-ом:


передача внутренних полей после проверки наличия объекта
/* @flow */

type Person = {name: string, email: string};
type Bug = {id: string, assignee: ?Person};

var newBug: Bug = {id:'bug1', assignee: null};

if (newBug.assignee) {
  console.log(newBug.assignee.name);
  console.log(newBug.assignee.email);
}

асинхронный вызов после проверки наличия переменной
/* @flow */

function syncOp(y: number): number {
  return y;
}

function asyncToSyc(x: ?number) {
    if (x) {
      setTimeout(() => syncOp(x), 100);
    }
}

Согласен, что в некоторых случаях такие конструкции могут породить ошибки, но конкретно эти примеры содержат вполне безопасный код.
И это печально, что flow не смотря на "гораздо строгий и гораздо более мощный вывод типов, чем у TypeScript-а" не может разделять случаи, когда такое поведение безопасно, а когда — нет.


И вместо написания логики приложения, приходится выискивать способы, позволяющие flow мириться с твоим кодом =(

передача внутренних полей после проверки наличия объекта

Проверил, вот так работает без ругани:


type Person = {name: string, email: string};
type Bug = {id: string, assignee: ?Person};

var newBug: Bug = {id:'bug1', assignee: null};

if (newBug.assignee) {
  var assignee = newBug.assignee;
  console.log(assignee.name);
  console.log(assignee.email);
}

асинхронный вызов после проверки наличия переменной

Это тоже легко обойти исправлением типа. Наверно тут можно сделать скидку, что Flow сыроват?

И вместо написания логики приложения, приходится выискивать способы, позволяющие flow мириться с твоим кодом =(

Закончил сегодня переезд с PropTypes на Flow. На очереди редюсеры. И по ощущениям пляски вокруг Flow оправданы (я тоже очень не люблю, когда мне навязывают что-то сверх необходимого, похерил по этой причине redux-form, например). Выявлено несколько ошибок, которых не замечал раньше. Только WebStorm тормозит опять, зараза. Как с eslint-ом было, пока не отрубил все лишнее.

А можно ли заменить PropTypes на Flow для контекста? Насколько я представляю, пока от PropTypes отказаться нельзя, т.к. они используются для typehinting контекста.

Покажите проблемный участок кода. Будем работать. :)

Я имею в виду:

class Button extends React.Component {
  render() {
    return (
      <button style={{background: this.context.color}}>
        {this.props.children}
      </button>
    );
  }
}

Button.contextTypes = {
  color: PropTypes.string // Как получить контекст без PropTypes?
};
Мы честно попытались, грубо говоря, переименовать проект из JS в TS — оно не заработало. Оно не компилируется, потому что некоторые вещи, с точки зрения TypeScript-а являются некорректными. Это не означает, что TypeScript — плохой язык, но продвигаться на идее надмножества, и подводить меня так, TypeScript — я не ожидал.

Вы неверно понимаете эту идею. TS является надмножеством JS, т.к. полностью поддерживает синтаксис и семантику последнего. Но поскольку TS призван обеспечить статическую типизацию, т.е. является более строгим с т.з. type safety, разумеется, простое изменение расширения файла не работает. Иначе какой смысл переходить на TS?

Тем не менее, разработчики языка учли проблемы миграции и поэтому ввели в конфиг всякие noImplicitAny, allowUnreachableCode и прочие ослабляющие параметры. Проще говоря, включите их все — и простого переименования будет достаточно.

И тут на помощь приходит восхитительнейший плагин, который для меня является киллер-фичей, почему сейчас я выберу Flow, а не TypeScript

Поверхностный гуглеж предолжил мне, как минимум, это: Runtypes, Reflec-TS. Наконец, есть генерация в JSON Schema, на котором построено много runtime-валидаторов.
Sign up to leave a comment.

Articles