[英]How to define param names and types for a function which accepts 1 parameter or 2 parameters, in typescript?
[英]How to define a function which only accepts parameters which may be a type in typescript?
我想定义一个函数,如:
function isNumber(param: ???): param is number {
}
如果参数可能是一个数字,例如number | string
number | string
, number | boolean
number | boolean
,它可以传递给函数。 如果不是,例如它的类型是string
或boolean
,就会出现编译错误。
是否可以定义这样的类型?
从概念上讲,您希望isNumber()
在param
的类型T
中通用,但您希望T
的下限为number
。 这与被认为是上限的正常extends
约束相反。 不幸的是,TypeScript 不直接支持下界泛型。 这是在microsoft/TypeScript#14520中请求的,如果它曾经实现过,它可能会使用super
而不是extends
并且看起来像
// NOT VALID TS (as of 4.7), DON'T DO THIS
function isNumber<T super number>(param: T): param is number {
return typeof param === "number"
}
但是,正如我所说,我们不能这样做。
相反,我们可以通过在条件类型上使用常规上限来模拟下界泛型。 像T extends (U extends T ? unknown : never)
这样的东西会表现得有点像T super U
。 如果T
是U
的超类型,则(U extends T ? unknown : never)
计算结果为unknown
,因此满足约束 ( T extends unknown
)。 否则, (U extends T ? unknown : never)
的计算结果为never
,因此可能不满足约束 ( T extends never
)(除非T
never
自身,无法通过这种方式进行防范)。
在您的情况下,如果T
是number
的超类型或子类型,我们实际上很好,所以我们可以写T extends (number extends T ? unknown : number)
并且如果T
恰好是像14
这样的数字文字类型,那么一切仍然作品。
一个问题是编译器不明白param
可能是number
的超类型,所以你不能返回类型谓词param is number
。 相反,您需要编写编译器认为可分配给T
(和number
)的类型。 所以我们将使用交集param is T & number
。
所以这里是:
function isNumber<T extends number extends T ? unknown : number>(
param: T
): param is number & T {
return typeof param === "number"
}
让我们测试一下:
isNumber("oops"); // error, Argument of type 'string' is
// not assignable to parameter of type 'number'.
isNumber(Math.random() < 0.5 ? "abc" : 123); // okay
isNumber(14); // okay
看起来不错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.