如果TypeScript可以保护我免受空数组的侵扰,我会很乐意。
我已经看到很多类似这样的运行时错误
const emptyArr: Array<{ prop: string }> = []
causesError = emptyArr[0].prop
TypeError:无法读取未定义的属性'foo'
编码人员可能想做:
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似乎无法基于 longityness 检查来缩小Array<T> | void[]
或类似类型,这可能是我想要的东西的必要条件。
答案 0 :(得分:1)
如果要在编译时保护自己免受空数组的侵害,可以在Typescript 3中定义一个泛型类型,该泛型类型要求在第一个索引处有一个项目,随后需要多个项目。例如:
type NonEmptyArray<T> = [T, ...Array<T>];
const notValid: NonEmptyArray<number> = []; // compilation error!
const valid1: NonEmptyArray<number> = [1];
const valid2: NonEmptyArray<number> = [1, 1, 2, 3, 5, 8];
请注意,由于类型定义中的其余(...
)表达式,因此这仅在打字稿3中有效。
答案 1 :(得分:1)
您可以使用用户定义的类型防护:
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支持通常检查与数组长度有关的检查。