typescript - 为什么 Typescript 编译器认为字符串数组中的元素类型为“从不”?
问题描述
我有一个在 Typescript 3.5.3 中编译得很好的函数,但是在更新到 3.8.3 之后,在编译过程中会抛出一个难以理解的错误。
import { isNumber, toInteger, padNumber } from './math';
parse(value: string): NgbDateStruct {
if (value) {
const dateParts = value.trim().split('/');
if (dateParts.length === 3
&& isNumber(dateParts[0])
&& isNumber(dateParts[1])
&& isNumber(dateParts[2])
// force user to enter 4 digit year
&& dateParts[2].length === 4) { // <-- fails here
return {month: toInteger(dateParts[0]), day: toInteger(dateParts[1]), year: toInteger(dateParts[2])};
}
}
return null;
}
该dateParts
变量是一个字符串数组 - 那么为什么在检查第三个元素的长度时,dateParts[2].length
编译器会认为取消引用的值的类型是never
???
编译产生以下错误:
ERROR in src/app/shared/utils/datepicker-parser-formatter.ts:17:25 - error TS2339: Property 'length' does not exist on type 'never'.
17 && dateParts[2].length === 4) {
~~~~~~
isNumber
定义为:
export function isNumber(value: any): value is number {
return !isNaN(toInteger(value));
}
解决方案
isNumber
定义不正确。它断言任何可以转换为数字的东西都是数字。这是两个不同的东西。正确的定义是这样的:
export function isNumber(value: any): value is number {
return typeof value === "number" && !isNaN(value);
}
...如果您想要过滤掉的东西NaN
。(我没有过滤掉 fractionsl 值。)
正如@jtbandes 所说,既然isNumber
告诉 TypeScript 那dateParts[2]
是 a number
,但 TypeScript 知道split
它是一个字符串,它正在尝试应用string & number
- 这是never
.
isNumeric
对于像这样你知道它不是数字的地方,你会想要一个或类似的东西:
export function isNumeric(value: any): boolean {
return !isNaN(toInteger(value));
}
请注意,它不会做出断言。
推荐阅读
- python-3.x - 读取pdf文件并使用python将单词存储在列表中
- javascript - 为什么 ARM 芯片的指令名称中带有 Javascript(FJCVTZS)?
- ruby-on-rails - 可以使用会话 cookie 保护 Rails API
- c++ - C++ 代码::block 花括号样式
- php - 循环遍历具有不同值的缓冲区内容
- android - 从单元测试调用时,代码未在 asyncTask 内部执行
- node.js - Nodejs FS模块没有返回这样的文件或目录错误
- kendo-ui - 仅当用户想要编辑特定行时,如何检索网格行的附加数据以进行编辑?
- objective-c - Swift 项目中带有 .a 库 Xcode 的架构 arm64 的未定义符号
- json - Typo3:登录后显示用户特定的 Json 文件