流类型:“可选功能参数”和“可能类型”之间的差异

问题描述 投票:1回答:1

有人可以解释“可选功能参数”和“可能类型”之间的区别,如Flow文档的on this page所述?

这些定义非常相似:

也许类型:“也许类型适用于值是可选的地方”

可选功能参数:“功能可以有可选参数,其中问号?在参数名称后面。”

我从语法角度理解这些差异。但是,听起来两者都会在您想要为函数定义可选参数的情况下使用。你会在哪里使用一个?

javascript types flowtype flow-typed
1个回答
2
投票

没有区别。但它们也是完全不同的东西。

我认为这里存在一些概念混淆。以下是可选参数的示例:

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,所以flow期望将boolean作为第二个参数传递。当我们不传递布尔值时,flow会抛出错误。我们的参数不再是可选的。我们可以从lower中删除类型,但是然后flow会将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,并且通过输入lower作为void | boolean,我们告诉流量lower可以是booleanundefined(未指定为参数)。

所以这显然是一种非常常见的情况。事实上很常见,在某些时候我们可能会考虑封装它。这可以通过泛型完成,如下所示:

// 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.