打字稿参数中允许的最小数字

伊法鲁基

我有一个像这样的功能:

function getBlogs(limit?: number) { ... }

limit只能是一个正整数,它不能是0

我怎么告诉打字稿这个数字只能大于0?

贾卡尔兹

有一个公开的建议microsoft / TypeScript#15480支持“范围类型”,在这里您可以说一些类似的东西type PositiveWholeNumbers = 1..9999999来表示您的类型。还有一个(封闭的)建议microsoft / TypeScript#4639支持intuint-like类型,在这里也可能起作用。遗憾的是,这两种方法都没有实现,因此,如果要在类型系统中进行此操作,则需要做其他事情。


如果(在千有一个相当小的上限最多),您可以手动生成一个工会的容许值以及在库文件中的某个地方推它。可以以编程方式完成此操作,因此您无需进行物理输入,但与您输入的内容相同:

// Evaluate the following in JS and copy into your code somewhere
// "type AllowableValues = "+
//   Array.from({length: 5000}, (x, i) => String(i+1)+((i+1)%100?"":"\n")).join(" | ")+";";
// which produces:

type AllowableValues = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | // and so on

function getBlogs(limit?: AllowableValues) {
  console.log((limit || 0).toFixed());
}

从某种意义上说,这将起作用,编译器将limit在并集(或undefined)中看到某个数字值,并且getBlogs()将针对该数字值调用进行验证:

getBlogs(100); // okay
getBlogs(1); // okay
getBlogs(1.5); // error!
// ----> ~~~
// Argument of type '1.5' is not assignable to 
// parameter of type 1 | 2 | 3 | ...
getBlogs(0); // error!
// ----> ~
// Argument of type '0' is not assignable to 
// parameter of type 1 | 2 | 3 | ...
getBlogs(-4);
// ----> ~~
// Argument of type '-4' is not assignable to 
// parameter of type 1 | 2 | 3 | ...

当然,超出范围的任何操作都会失败:

getBlogs(1234567); // error (too big)
getBlogs(1e100); // error (too big)

这仅在人们getBlogs()使用某些数字文字进行调用时才有效数学运算容易产生number,其范围太广而无法验证:

getBlogs(3+1); // error: safe but the compiler can't tell

另外我还注意到,像上面这样的大型联合会陷入困境,足以使我的IDE呆滞,所以我真的只建议对多达数百个数字进行此操作。


另一种可能性是制作getBlogs()一个泛型函数,其中对参数进行验证以确保其为正整数。我认为,您可以使用模板文字类型在TypeScript 4.1中完成此操作

type AsPositiveWholeNumber<N extends number> =
  N extends 0 ? PositiveWholeNumber :
  number extends N ? PositiveWholeNumber :
  `${N}` extends `${infer F}${"." | "-"}${infer L}` ?
  PositiveWholeNumber : N

type PositiveWholeNumber = {
  ["Please choose a value that is a positive whole number"]: number
} & number

function getBlogs<N extends number>(limit?: AsPositiveWholeNumber<N>) {
  console.log((limit || 0).toFixed());
}

在此,该getBlogs()函数接受limittype参数AsPositiveWholeNumber<N>,其中N是一个numberlimit传入值推断的-约束类型参数AsPositiveWholeNumber<N>设计类型的目的是,如果N是正整数,AsPositiveWholeNumber<N>则将为N否则,它将是PositiveWholeNumber伪类型,其目的是向用户提供看似有用的错误消息。

重要的工作在内部完成AsPositiveWholeNumber<N>首先,我们确保N既不是也不number0然后,我们通过模板文字类型将其转换为字符串`${N}`,然后确保此字符串版本N包含no".""-"字符。这至少应该将正整数与其他数字区分开,至少直到我们得到一个巨大的值,该值是整数,但其字符串表示形式以小数点形式表示(例如1.23456789e+23)。

让我们看看它是否有效:

getBlogs(100); // okay
getBlogs(1); // okay
getBlogs(1.5); // error!
// ----> ~~~
// Argument of type '1.5' is not assignable to 
// parameter of type 'PositiveWholeNumber | undefined'
getBlogs(0); // error!
// ----> ~
// Argument of type '0' is not assignable to 
// parameter of type 'PositiveWholeNumber | undefined'
getBlogs(-4);
// ----> ~~
// Argument of type '-4' is not assignable to 
// parameter of type 'PositiveWholeNumber | undefined'

getBlogs(1234567); // okay
getBlogs(1e100); // okay, but
getBlogs(11e98); // error: becomes 1.1e+99
getBlogs(3 + 1); // error: safe but the compiler can't tell

这样也可以。在您需要getBlogs()使用数字文字进行调用并且number不会接受任何-typed参数的情况下,存在相同的问题与纯联合相比,该解决方案肯定具有更多奇怪的运动部件,因此我不确定我是否真的会在任何生产代码中推荐这样做。但是我确实想展示TypeScript当前距离您想要的行为有多近。


操场上的代码链接

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

n的数字乘积的最小数字

来自分类Dev

仅使用允许的数字来构建大于K的最小数字

来自分类Dev

第k个最小数字

来自分类Dev

从给定列表中选择最小数字以给出总和 N(允许重复)

来自分类Dev

选择范围内的最小数字

来自分类Dev

如何计算ArrayList中的最小数字?

来自分类Dev

Java:查找数组中大于零的最小数字

来自分类Dev

打印输入的最小数字(不包括任何负数)

来自分类Dev

Java:两个最小数字helo

来自分类Dev

随机数组中的最小数字及其索引

来自分类Dev

获取文件中最小数字的索引

来自分类Dev

如何获得 Common Lisp 中最小数字和第二小数字之间的范围?

来自分类Dev

获取小数点后的第二个最小数字

来自分类Dev

缩小数字范围

来自分类Dev

不能由数组中的数字之和形成的最小数字

来自分类Dev

在数字列表中查找最小数字的递归方法

来自分类Dev

FInd下一个相同数字的最小数字Python

来自分类Dev

给定用户3位数字,找到并打印它的最小数字

来自分类Dev

如何正确获得数字序列中的最大和最小数字?

来自分类Dev

成对交换数字的第三大和最小数字

来自分类Dev

Python:列表中的最小数字,包括重复数字

来自分类Dev

从用户输入的数字中显示最大和最小数字 C++

来自分类Dev

在包含字符串和数字的二维数组中查找最小数字

来自分类Dev

如何在C中找到数字中的最小数字及其在向量中的位置?

来自分类Dev

为什么打字稿允许默认参数先于必需参数?

来自分类Dev

为什么打字稿允许默认参数先于必需参数?

来自分类Dev

为什么打字稿中允许使用任何类型?在编译时很难捕获错误的地方

来自分类Dev

查找不会作为字符串子序列出现的最小数字

来自分类Dev

2D数组中的最小数字无法正常工作

Related 相关文章

  1. 1

    n的数字乘积的最小数字

  2. 2

    仅使用允许的数字来构建大于K的最小数字

  3. 3

    第k个最小数字

  4. 4

    从给定列表中选择最小数字以给出总和 N(允许重复)

  5. 5

    选择范围内的最小数字

  6. 6

    如何计算ArrayList中的最小数字?

  7. 7

    Java:查找数组中大于零的最小数字

  8. 8

    打印输入的最小数字(不包括任何负数)

  9. 9

    Java:两个最小数字helo

  10. 10

    随机数组中的最小数字及其索引

  11. 11

    获取文件中最小数字的索引

  12. 12

    如何获得 Common Lisp 中最小数字和第二小数字之间的范围?

  13. 13

    获取小数点后的第二个最小数字

  14. 14

    缩小数字范围

  15. 15

    不能由数组中的数字之和形成的最小数字

  16. 16

    在数字列表中查找最小数字的递归方法

  17. 17

    FInd下一个相同数字的最小数字Python

  18. 18

    给定用户3位数字,找到并打印它的最小数字

  19. 19

    如何正确获得数字序列中的最大和最小数字?

  20. 20

    成对交换数字的第三大和最小数字

  21. 21

    Python:列表中的最小数字,包括重复数字

  22. 22

    从用户输入的数字中显示最大和最小数字 C++

  23. 23

    在包含字符串和数字的二维数组中查找最小数字

  24. 24

    如何在C中找到数字中的最小数字及其在向量中的位置?

  25. 25

    为什么打字稿允许默认参数先于必需参数?

  26. 26

    为什么打字稿允许默认参数先于必需参数?

  27. 27

    为什么打字稿中允许使用任何类型?在编译时很难捕获错误的地方

  28. 28

    查找不会作为字符串子序列出现的最小数字

  29. 29

    2D数组中的最小数字无法正常工作

热门标签

归档