有一个公开的建议,
microsoft/TypeScript#15480
支持“范围类型”,您可以这样说,
type PositiveWholeNumbers = 1..9999999
代表您的类型。还有一个(封闭的)建议
microsoft/TypeScript#4639
支持
int
和
uint
-就像类型一样,也可能在这里工作。遗憾的是,这两个都没有实现,因此如果您想在类型系统中实现这一点,您需要做一些其他的事情。
如果有一个合理的小上限(以千为单位
最多
),您可以手动生成
union
并将其放入库文件中的某个位置。这可以通过编程方式完成,因此您不必实际键入,但这与您键入的内容相同:
type AllowableValues = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
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);
getBlogs(1e100);
这只在人们打电话的时候起作用
getBlogs()
使用一些数字文字。数学运算往往产生
number
,太宽,无法验证:
getBlogs(3+1);
我还注意到,像上面这样的大联盟会使我的IDE变得迟钝,所以我真的只建议对几百个以下的数字这样做。
另一种可能性是
getBlogs()
A.
generic
函数,在此函数中验证参数以确保其为正整数。我认为,您可以在TypeScript 4.1中使用
template literal types
:
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()
函数接受
限度
类型的参数
AsPositiveWholeNumber<N>
哪里
N
是一个
数字
-由的值推断的约束类型参数
限度
已传入。这个
AsPositiveWholeNumber<N>
类型的设计应确保
N
是一个正整数,那么
AsPositiveWholeNumber<N>
只会是
N
.否则
PositiveWholeNumber
,一种虚拟类型,其目的是向用户提供一条看似有用的错误消息。
重要的工作在内部完成
AsPositiveWholeNumber<N>
.首先我们要确保
N
两者都不是
数字
也没有
0
。然后通过模板文本类型将其转换为字符串
`${N}`
然后确保
N
不包含
"."
或
"-"
字符。这应该主要区分正整数和其他数字,至少在我们得到
巨大的
值,这些值是整数,但其字符串表示形式以带小数点的指数表示法呈现(例如
1.23456789e+23
)。
让我们看看它是否有效:
getBlogs(100);
getBlogs(1);
getBlogs(1.5);
getBlogs(0);
getBlogs(-4);
getBlogs(1234567);
getBlogs(1e100);
getBlogs(11e98);
getBlogs(3 + 1);
所以这也是可行的。你需要打电话的地方也有同样的问题
getBlogs()
用一个数字文字
数字
-将不接受类型化参数。这个解决方案肯定比纯联合有更多奇怪的运动部件,所以我不确定我真的会在任何生产代码中推荐它。但我确实想展示TypeScript目前与您期望的行为有多接近。
Playground link to code