typescript - 从空数组访问对象属性时如何使 TypeScript 编译失败

标签 typescript

如果 TypeScript 能够保护我免受空数组的影响,我会很高兴。

我见过不少发生类似情况的运行时错误

const emptyArr: Array<{ prop: string }> = []
causesError = emptyArr[0].prop

TypeError: Cannot read property 'foo' of undefined

编码员可能想要这样做:

const emptyArr: Array<{ prop: string }> = []
if (emptyArr.length > 0) {
   noMoreError = emptyArr[0].prop
}

我觉得 TypeScript 应该能够推断数组可能为空,并能够就此发出警告。

我尝试了以下内容,但仍然无法使其工作:

interface PossiblyEmptyArray<T> extends Array<T> {
  [i: number]: T | undefined;
}
const arr: PossiblyEmptyArray<{ prop: string }> = []
arr[0].prop // fails at runtime still

我相信这种行为在 TypeScript 2.x 和 3.0 之间是一致的

它实际上确实工作几乎就像我想要的那样,没有 extends Array少量。 但这是一个不应该出现的编译时错误:

interface PossiblyEmptyArray<T> {
  [i: number]: T | undefined;
  length: number
}
const arr: PossiblyEmptyArray<{ prop: string }> = []
if (arr.length > 0) {
  arr[0].prop // no "prop" on string | undefined
}

与此类型的结果相同:

type PossiblyEmptyArray<T> = Array<T> | void[]

编辑:

我越看越觉得 TS 似乎无法缩小范围 Array<T> | void[]或基于长度检查的类似类型,这可能是我想要的先决条件。

最佳答案

您可以使用用户定义的类型保护:

type PossiblyEmptyArray<T> = (T | undefined)[];
type NonemptyArray<T> = [T, ...(T | undefined)[]];

function isNonempty<T>(arr: PossiblyEmptyArray<T>): arr is NonemptyArray<T> {
  return arr.length > 0;
}

const arr: PossiblyEmptyArray<{ prop: string }> = []
if (isNonempty(arr)) {
  arr[0].prop
}

但是,除了检查恒定数量的元素之外,这种方法并不能推广,除非您使用花哨的品牌类型。 TypeScript 团队 considered and decided against一般支持检测对数组长度的检查。

关于typescript - 从空数组访问对象属性时如何使 TypeScript 编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51777424/

相关文章:

typescript - 有没有办法在 TypeScript 中自动完成类属性?

node.js - Express + TypeScript : Create type inference for response. 本地人

node.js - Typescript从 Node 模块导入ts文件

angular - 没有导出成员 'toPromise' rxjs- 5.5.2

Angular 5 HttpClient HttpTestingController 测试报错路径

javascript - 如何编辑和呈现存储为字符串的内部 html?

typescript - 预期有 3 个类型参数但得到 1 个但它应该推断出 2 种类型

javascript - 如何将字符串数组转换为 typescript 类型?

angular - 如何在 HTTPGET 上动态添加标记到谷歌地图组件(Angular 6)

angular - 使用 ngx-bootstrap modal 将数据传递给 modal