我正在尝试创建一个使用数字或字符串'last'并使用数组中相应元素的函数。
我处理输入为“ last”的情况。
我添加了一个简化的示例。 TS Playground
在return state[i]
行上出现错误。
我尝试将dispatch...
移至(typeof i === 'number')
的if块,但这也不起作用。
export function moveTo(i: number | 'last') {
return (dispatch: Function, getState: ()=>string[]) => {
const state = getState();
if (i === 'last') {
i = state.length - 1;
}
dispatch({
index: i, //here i is shown to be number on hover
effect() {
return state[i]; // index expression is not of type number (shows as number | 'last')
}
});
};
}
我想在if语句之后断言i
是number
,这样我就不必在效果函数中的任何地方都使用as number
。
答案 0 :(得分:2)
由于i
可能是string
和number
的一小部分,他们努力理解这种转换。一种解决方案是使用另一个变量:
export function moveTo(i: number | 'last') {
return (dispatch: Function, getState: ()=>string[]) => {
const state = getState();
const index: number = (i == 'last') ? state.length - 1 : i;
dispatch({
index,
effect() {
return state[index];
}
});
};
}
此外,同一变量具有多种类型(这可能会发生)是一件坏事,我建议使用-1
而不是'last'
来保持number
类型。
答案 1 :(得分:1)
i
回调中effect
的类型未缩小,因为i
被认为是函数moveTo
的可变参数。
这意味着,在以后某个时间调用effect
回调时,编译器无法确定i
仍然具有number
类型。结果,由if (i === 'last') {i = state.length - 1;}
引起的类型保护失效,并且i
在回调中获得了初始的number | 'last'
类型。
那么TS何时将功能参数视为const
?
函数参数为implicitly treated as const
,直到您在函数或嵌套函数中的某个位置对参数进行了分配。当参数是隐式const
时,仍可以通过control flow analysis / type防护在嵌套函数表达式和箭头函数中访问其缩小的类型。因此,这个人为设计的example可以工作:
export function moveTo(i: number | 'last') {
return (dispatch: Function, getState: () => string[]) => {
if (i !== 'last')
dispatch({
index: i,
effect() {
return getState()[i];
}
})
};
}
现在该怎么办?
您最好的选择可能是declare a new const
variable(另请参阅@D。Nathanael的答案),它比回调中的as number
产生更一致的类型。 Airbnb JavaScript Style Guide不建议您重新分配函数参数,因此您可以将i
视为不可变的,从而有机会稍微clean up编写代码。