我如何将数组检查转换为函数,并且不会在代码中的数组检查位置出现错误?
原来的函数体是“start”,我打算把函数体变成“start1”。然而,当我这样做时,一个错误显示在行中,如下所示。
type JSONRPCParams = object | any[]; // this is in another module where I cannot change the source
async function start(params: JSONRPCParams | undefined) {
// the intention is to turn the following check into a function
if (!params || !Array.isArray(params) || params.length === 0) {
throw new Error('invalid parameter(s) provided');
}
const assetConfig = params[0]; // this is ok when the check is inline
}
function validateParams(params: JSONRPCParams | undefined) {
if (!params || !Array.isArray(params) || params.length === 0) {
throw new Error('invalid parameter(s) provided');
}
}
async function start1(params: JSONRPCParams | undefined) {
validateParams(params);
const assetConfig = params[0]; // this is not ok, when the check becomes a function
}
错误是:'params'可能是'undefined'。ts(18048)Element隐式具有'any'类型,因为类型'0'的表达式不能用于索引类型'JSONRPCParams'。属性“0”在类型“JSONRPCParams”上不存在。ts(7053)
我也试着写validateParams如下,但它不工作,与上面看到的相同的错误。
if (params && Array.isArray(params) && params.length >= 0) {
return;
}
throw new Error('Invalid parameter(s) provided');
我如何编写validateParams函数,以便在start1函数中,我不会在注解行上得到错误?
我研究过其他类似的Stackoverflow问题,但它们不能处理这个问题。
您的专业知识和帮助是赞赏。
谢谢你。
2条答案
按热度按时间6ioyuze21#
控制流分析,如真实性检查的结果(如
if (params) { }
)或类型保护函数的结果(如theArray.isArray()
method)不会跨函数边界传播。这是为了使编译器易于处理控制流分析而做出的权衡;关于这个一般问题的大量讨论,请参见microsoft/TypeScript#9998。本质上,在函数体内部发生的任何收缩在函数外部都是看不到的,因此在validateParams(xxx)
体内检查params
参数对函数外部的xxx
的表观类型没有影响。如果您希望这样做,您需要将
validateParams
注解为Assert函数,并告诉编译器主体如何缩小其参数。例如:返回类型是 * Assert predicate *
asserts params is any[]
,这意味着在调用validateParams(xxx)
之后,xxx
的类型将从可分配给JSONRPCParams | undefined
的某个类型缩小到可分配给any[]
的某个类型。请注意,您正在 * 通知 * 编译器该函数如何缩小。编译器不会 * 验证 * 它是否这样做。您可以用任何逻辑替换
validateParams()
的主体,并且不会出现编译器错误。例如,完全没有逻辑:所以要小心。
无论如何,现在你的
start1()
函数将按预期工作:您可以看到
validateParams()
能够缩小到比any[]
更具体的内容,具体取决于输入:这里
x
已经从number[] | undefined
缩小到number[]
,而不仅仅是any[]
。Playground链接到代码
e4yzc0pl2#
我最近遇到了类似的问题,但我想返回一个布尔值。我是这样做的:
我也把这个问题作为参考:What does the
is
keyword do in typescript?