Тип потока: разница между «необязательными параметрами функции» и «возможно типами» - PullRequest
0 голосов
/ 28 февраля 2019

Может ли кто-нибудь объяснить разницу между "необязательными параметрами функции" и "возможно типами", как описано на на этой странице документации Flow?

Определения звучат очень похоже:

Возможно типы:"Возможно типы предназначены для мест, где значение является необязательным"

Необязательные параметры функции:"Функции могут иметь дополнительные параметры, гдепосле имени параметра стоит знак вопроса? "

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

1 Ответ

0 голосов
/ 28 февраля 2019

Разницы нет.Но также это совершенно разные вещи.

Я думаю, здесь есть некоторая концептуальная путаница.Вот пример необязательного параметра:

function recase(str, lower) {
  if (lower) {
    return str.toLowerCase();
  }

  return str.toUpperCase();
}

recase('Test', true)
// "test"
recase('test')
// "TEST"
recase()
// Uncaught TypeError: Cannot read property 'toUpperCase' of undefined

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

Обратите внимание, что я не вводил никаких типов.Это потому, что «необязательный параметр» здесь - это просто общая концепция программирования.Flow не имеет встроенной функции, называемой «необязательные параметры».Что предлагает поток, так это способ вводить необязательных параметров, называемых "возможно типами".

Итак, я хочу напечатать свою функцию выше.Ну, первый проход может выглядеть так:

// We're taking a string and a boolean and returning a string, right?
function recase(str: string, lower: boolean): string {
  if (lower) {
    return str.toLowerCase();
  }

  return str.toUpperCase();
}

recase('Test', false)
// "TEST"
recase('Test', true)
// "test"
recase('Test')
// ^ Cannot call `recase` because function [1] requires another argument.

Поскольку мы ввели lower как boolean, поток ожидает, что boolean будет передан как второй аргумент.Когда мы не передаем логическое значение, поток выдает ошибку.Наш параметр больше не является обязательным.Мы можем просто удалить тип из lower, но тогда поток по умолчанию будет lower для any типа, что означает, что пользователь может передавать все, что он хочет, что делает наши типы неоднозначными и подверженными ошибкам.Вот что мы могли бы сделать:

function recase(str: string, lower: void | boolean): string {
  if (lower) {
    return str.toLowerCase();
  }

  return str.toUpperCase();
}

recase('Test', true)
// "test"
recase('Test')
// "TEST"

В потоке тип void соответствует только значению undefined.Если мы не предоставляем значение для lower при вызове recase, тогда значение lower будет undefined, и, набрав ниже как void | boolean, мы сказали потоку, что lower может быть либоboolean или undefined (не указывается в качестве параметра).

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

// Let's call this Q for "Question" but it's nice and short
type Q<T> = void | null | T;

function recase(str: string, lower: Q<boolean>): string {
  if (lower) {
    return str.toLowerCase();
  }

  return str.toUpperCase();
}

Обратите внимание, что мы добавили null к нашему универсальному типу, потому что регистр undefined сильно совпадает с регистром null желаниябыть в состоянии передать null для необязательных параметров.

Ну, это настолько распространено, что поток предлагает нам то, что составляет синтаксический сахар для этой ситуации, называемый «возможно типами».Если бы вы смогли переименовать наш тип Q в ?, то у вас были бы, возможно, типы.

function recase(str: string, lower: ?boolean): string {
  if (lower) {
    return str.toLowerCase();
  }

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