Автор оригинала: FreeCodeCamp Community Member.
Этот пост предназначен для скептиков и новичков для систем типа и направлен на сформулировать, а не тяжело продать.
- Сначала мы посмотрим на то, как в вашем динамическом типом кодировании появляются конвенции по статическим типам.
- Затем мы вернемся и попытаемся подумать о том, что это явление рассказывает нам о том, как мы хотим кодировать.
- Наконец, мы спросим некоторые (ведущие!) Вопросы, которые должны возникнуть из этих пониманий.
1А: типы в именах
Независимо от языка, ваше путешествие с типами начинается почти как только вы научитесь кодируете. Базовая структура данных списка приглашает соответствующее множественное число:
var dog = 'Fido' var dogs = ['Fido', 'Sudo', 'Woof']
По мере того, как вы работаете с всеобъемлющим кодом, вы начинаете образовывать мнения, которые вы можете марифовать в команде или руководство по стилю:
- Всегда используйте конкретные имена, такие как
Dogid
противDogName
противDogBreed
или пространство имен/класс/объект, какDog.name
илисобака или
порода собакиОсобенности не должны быть подстроками множеств, например, Плохо:
- Блог
и
БлогиХорошо:
Blogpostпротив
блоглистЛогины
- должен иметь префикс Boolean-ish , как загружает
,
Hasproperty,
DidchangeФункции с побочными эффектами должны иметь глаголы
- Внутренние переменные должны иметь
- _приставка
Это может показаться тривиальным, так как мы говорим о именах переменных, но эта вена работает Чрезвычайно глубокий. Имена в нашем кодировании отражают концепции и ограничения, которые мы размещаем в нашем коде, чтобы сделать его более ремонтом в масштабе:
- Председательные компоненты против состоятельных/подключенных контейнеров
- Атомы, молекулы, организмы, шаблоны, страницы
- Концепции, действия, операнды (одно из самых успешных названий грамматиков когда-либо)
- Block__Element – модификатор
- Компоненты высшего порядка
Все это просачивается в ваш код соответственно: * Контейнер
, * Компонент
, * Редуктор
, * Шаблон
, * Страница
, с *
Отказ
Как только вы начнете пересекать парадигмы исполнения, вы начинаете ощущать свой путь в подсказки монадического типа.
Node.js чувствовал это рано:
fs.readFile(myfile, callback) fs.readFileSync(myfile) // introduced when people realized callback hell might not be worth non-blocking
Реагировать введен использовать
Префикс, чтобы указать зацепление в среду выполнения, которые должны уважать определенные правила :
function Component() { const [bool, setBool] = React.useState(true) React.useEffect(callback) const foo = useCustomHook() // ... }
Я лично увлекаюсь напоминанием о Nululability:
const maybeResult = await fetchAPI() if (maybeResult) { const result = maybeResult // do things with result } else { // maybeResult is falsy, dont assume it is there }
Почти все, что вы называете, вы уже используете типы.
Так что, спросите?
Продолжайте читать, я наращиваю это.
1b: типы в структурах данных
Проблема с типами кодирования в именах заключается в том, что язык, вероятно, не заботится о ваших тщательном именованных переменных (действительно, в Javascript, он, вероятно, становится беспощадно добываемым вне признания). Он с радостью запускает ваш код и бросит ошибку выполнения, если вы забудете уважать свои собственные имено. Что, если мы сделали типы формально проверяемых через структуры данных?
Наиболее основными являются константами. В redux это Общий для явно (и избыточно) установить Screaming_Case_Constants :
const ADD_TODO = 'slice/ADD_TODO' // later in redux code: import { ADD_TODO } from './redux/types' switch (action.type) { case ADD_TODO: // do stuff based on the action // ... }
Это в основном сделано, потому что вы не можете доверять своему товарищему за разработчику не опечатывать их строки.
Однако даже эти строки предложили слишком много доверия, и мы нашли его достаточно важными, чтобы добавить новую языку, чтобы гарантировать уникальность:
const ADD_TODO = Symbol('slice/ADD_TODO')
Мы также подделываем нами путь к поводу этого:
const colors = { BLUE: Symbol(1), GREEN: Symbol(2), RED: Symbol(3), }
Но простые значения (строки, цифры, логические значения) на самом деле легко сравнивать и лечить соответственно.
Больше нажатия – это типы кодирования в сложных значениях.
Обычно это происходит, когда у вас есть массивы объектов, а объекты различны в некоторых отношениях и похожих в других:
const animals = [{ name: 'Fido', legs: 4, says: 'woof' }, { name: 'Kermit', legs: 2, marriedTo: 'Piggy' }] // will have bugs if an animal with both `says` and `marriedTo` exists animals.forEach((animal) => { if (animal.says) { // i guess it's a dog? } if (animal.marriedTo) { // i guess it's a frog? } })
Багги проверки и неявно предполагаемые типы часто являются причиной для большой боли. Лучше напечатать явно:
const animals = [ { type: 'dog', // new! name: 'Fido', legs: 4, says: 'woof', }, { type: 'frog', // new! name: 'Kermit', legs: 2, marriedTo: 'Piggy', }, ] animals.forEach((animal) => { if (animal.type === 'dog') { // must be a dog! } if (animal.type === 'frog') { // must be a frog! } })
Это на самом деле, что происходит для redux (и, достаточно интересно, удобно для других вещей, таких как дискриминированные союзы ), но вы увидите это Везде в GATSBY и Бабел и Реагировать И я уверен, что вы знаете о случаях, которые я не знаю.
Типы даже существуют в HTML: и
вести себя так иначе! (И я уже упомянул типы в CSS с Block__Element – модификатор )
Даже в HTML/CSS вы уже используете типы.
1С: типы в API
Я почти закончил. Даже за пределами вашего языка программирования интерфейсы между машинами включают типы.
Большие инновации в остальных были в основном примитивной формой печатания запросов клиента-сервера: Получить
, Поставить
, Пост
, Удалить
Отказ Веб-конвенции представили другие поля в запросах, например Примите кодировку
Заголовок, что вы должны придерживаться, чтобы получить то, что вы хотите. Тем не менее, спокойствие в основном не исполняется, и поскольку он не предлагает гарантии, нижестоящие инструменты не могут предположить правильно поведение конечных точек.
GraphQL принимает эту идею и набирает его до 11: типы являются ключом к запросам и мутациям и фрагментам, но также на каждом поле и каждую входную переменную, подтвержденную как на клиентах, так и на сервере. С гораздо более сильными гарантиями, он может отправить гораздо лучший инструмент как норма сообщества.
Я не знаю историю SOAP и XML и GRPC и других машин-машинных протоколов связи, но я готов ставку, есть сильные параллели.
Часть 2: Что это говорит нам?
Это было очень длинное, и но неисчерпая экспертиза типов пронизывает все, что вы делаете. Теперь, когда вы видели эти шаблоны, вы, вероятно, можете подумать о большем количестве примеров, которые я забываю прямо сейчас. Но на каждом повороте, кажется, что к большему обслуживающему коду кажется большему ремонту, а лучшим инструментом – это каким-то образом добавлять типы.
Я упомянул части этого тезиса в Как называть вещи , но в основном все схемы именования попадают под просвещенную форму венгерской обозначения, как описано в Джоэл Спольским Неправильный код выглядеть не так Отказ
Если никто из того, что я описал, резонирует с вами, и не то, что вы уже делали, то типы могут быть не для вас.
Но если это сделает, и вы делали это в слипке моды, вам может быть заинтересован в большем количестве структуры вокруг того, как вы используете типы в своем коде, и используете лучшую инструмент, который использует все усилия, которую вы уже помещаете в типы Отказ
Вы можете работать на ваш путь к системе типа, даже не зная его.
Часть 3: Надежные вопросы
Так что зная, что мы знаем сейчас о использовании типов в нашем коде без системы. Я попрошу трудные вопросы.
Вопрос 1: Что вы в настоящее время делаете, чтобы принудительные типы без системы типа?
На индивидуальном уровне вы занимаетесь оборонительным кодированием и ручной проверкой. В основном вручную гласил свой собственный код и рефлексивно добавляя проверки и охранников, не зная, если они действительно нужны (или, хуже, не делает это и выясняют, что после просмотра исключений запуска).
На уровне команды вы проводите кратные разрабатывающие часы в обзоре кода, приглашая велосипед пролить по именам, которые мы все знаем, очень весело.
Эти два процесса являются ручными методами, и очень плохое использование времени разработчика. Не будь плохим полицейским – Это разрушение командной динамики. В масштабе вы математически гарантированы провалы в качестве кода (поэтому, вызывающие производственные ошибки), либо потому, что все что-то пропустили, либо просто было недостаточно времени, и вам просто пришлось что-то отправить, или не было достаточно хорошего политика на месте еще.
Решение, конечно, состоит в том, чтобы автоматизировать его. Как говорит Ник Шрик, Делегировать для инструментов, когда это возможно Отказ Cretetier и Eslint поможет удерживать качество вашего кода – только в той степени, в которой программа может понять вас на основе AST. Он не предлагает никакой функции пересечения помощи и границы файлов – если функция Foo
Ожидает, что 4 аргумента, и вы проходите только 3, никто не будет кричать на вас, и вам придется защищать код внутри Foo
Отказ
Так что есть только так много, вы можете автоматизировать с линтом. Как насчет остальных, вы не можете автоматизировать?
В этом есть последний вариант: ничего не делай.
Большинство людей ничего не делают, чтобы обеспечить их неофициально разработанные системы типа.
Вопрос 2: Сколько из этих типов вы пишете себя?
Само собой разумеется, что если у всех ваших типовых политик созданы вами, то они должны быть написаны вами и применяются вами.
Это совершенно отличается от того, как мы пишем код сегодня. Мы сильно опирались на открытый источник – 97% современного веб-приложения из NPM Отказ Импортируем общий код, а затем записать последние части мили, которые делают наше приложение Special (AKA Business Logic).
Есть ли способ поделиться типами?
( Да )
Вопрос 3: Что, если ваши типы были стандартизированы?
Исследования показали, что программисты причина № 1 приняли к языку, является существующим возможностями и функциональными возможностями для их использования. Я учу Python использовать Tensorflow. Я узнаю цель C для создания собственного опыта iOS. Соответственно, JS был настолько успешным, потому что он проходит везде, усугубляется широкой доступностью бесплатного программного обеспечения с открытым исходным кодом, написанным другими людьми Отказ С некоторыми стандартизированными типами типа мы можем Типы импорта так же легко, как мы импортируем программное обеспечение с открытым исходным кодом написано другими людьми.
Так же, как GraphQL VS Отдых, стандартизированные типы в языке разблокируются намного лучше. Я предложу 4 примера:
Пример 1: быстрее обратная связь
Мы могли бы занять месяцы и дни, чтобы учиться у Ошибки времени выполнения И они подвергаются воздействию пользователей, поэтому они являются худшим возможным результатом.
Мы пишем тесты и применять правила Lint и другие проверки для перемещения этих ошибок в Построить временные ошибки , который сокращает циклы обратной связи в минуту и часы. (Как я недавно писал: Типы не заменяют тесты! )
Системы типа могут сократить эту обратную связь по еще другим порядкам, до секунды, проверка во время Запишите время Отказ (ЛИНТЕРЫ также могут сделать это. Оба условлены в условиях поддерживающей IDE, как VS-код) в качестве побочного эффекта, вы получаете автозаполнение бесплатно, поскольку проверка автозаполнения и записи – две стороны одной монеты.
Пример 2: Лучшие сообщения об ошибках
const Foo = { getData() { return 'data' }, } Foo['getdata']() // Error: undefined is not a function
JavaScript намеренно ленивый оценок по дизайну. Вместо страшного и нерепица undefined не функция
Во время выполнения мы можем переместить это, чтобы записать время. Вот сообщение об ошибке времени записи в тот же код:
const Foo = { getData() { return 'data' }, } Foo['getdata']() // Property 'getdata' does not exist on type '{ getData(): string; }'. Did you mean 'getData'?
Почему да, напечатает, я сделал.
Пример 3: Обозрение кромки
let fruit: string | undefined fruit.toLowerCase() // Error: Object is possibly 'undefined'.
Вплоть и выше встроенной отнулимой проверки (который заботится о таких вопросах, как прохождение в 3 аргументах, когда функция ожидает 4), система типа может максимально использовать ваши изменения (типы союза AKA). Я боролся с хорошим примером, но вот один:
type Fruit = 'banana' | 'orange' | 'apple' function makeDessert(fruit: Fruit) { // Error: Not all code paths return a value. switch (fruit) { case 'banana': return 'Banana Shake' case 'orange': return 'Orange Juice' } }
Пример 4: бесстрашный рефакторинг
Многие люди упомянули об этом, и я буду честен, что мне потребовалось долго, чтобы прийти к этому. Мышление – это: «Так что? Я не воспринимаю так много. Так что означает, что преимущество Skyscript меньше, чем вам, потому что я лучше, чем ты».
Это неправильно взять.
Когда мы начинаем исследуя проблему, мы начинаем с расплывной идеей решения. Когда мы прогрессируемся, мы узнаем больше о проблеме или изменении приоритетов, и если только мы не сделаем это миллион раз, мы, вероятно, выбрали что-то не так, будь то функциональные API, структура данных или что-то более широкое масштаб.
Вопрос в том, что тогда либо придерживайтесь его, пока он не нарушит, ни для рефакторов, когда вы можете ощутить, что вы собираетесь перерастить все, что у вас раньше. Я предполагаю, что вы принимаете, что часто пользуются рефакторингом. Так почему мы избегаем рефакторинга?
Причина, по которой вы откладываете этот рефактор, это то, что это дорого, а не потому, что это не выгодно для вас. Тем не менее, выделение его только увеличивает будущую стоимость.
Тип Системная инструментария помогает значительно снизить стоимость этого рефакторов, поэтому вы можете испытать преимущества ранее. Он снижает эту стоимость через более быструю обратную связь, проверку исчерпывающей способности и лучшие сообщения об ошибках.
Правда в рекламе
Существует затрата для систем типа обучения, которые вы не написали. Эта стоимость может компенсировать любую воображаемую выгоду для автоматической проверки типа. Вот почему я прилагаю много усилий, чтобы помочь снизить эту кривую обучения. Тем не менее, осознайте, что это новый язык и будет включать незнакомые концепции, а также, что даже инструменты представляют собой несовершенную работу в процессе.
Но это достаточно хорошо для Airbnb и Google и Атласский и Лифти и Priceline и Слабый И это может быть для вас.