在 Typescript 中使数组元素可以为空

Posted

技术标签:

【中文标题】在 Typescript 中使数组元素可以为空【英文标题】:Make an array element nullable in Typescript 【发布时间】:2021-01-28 23:08:26 【问题描述】:

我很惊讶这段代码没有错误:

let myList: string[] = require('something')

let foo: string | undefined = myList[7]

foo.length // no error!

如何使foo 具有string | undefined 类型?

我希望 typescript 编译器在第三行引发 Object is possibly 'undefined'.ts(2532)

【问题讨论】:

undefinednull 是两个不同的东西。你想要string | undefined 还是string | null?这与foo.includes('') 有什么关系?空字符串'' 既不是null 也不是undefined Nullable 指 undefined 和 null 我想让 tsc 在第三行说Object is possibly 'undefined'.ts(2532) 忘记空字符串,这是为了证明foo被认为是字符串,而不是string | undefined 【参考方案1】:

您可以将数组访问的结果“投射”到(string|undefined)

let myList : string[] = require('something');
let v = myList[7] as (string | undefined); //v will have type string|undefined
let uv = v.length;  //will give an error that v is possibly undefined

【讨论】:

【参考方案2】:

看起来 TypeScript 看到 myListstring[],因此检测到 myList[7] 的类型为 string

虽然它可分配string | undefined 类型的东西,TypeScript 确定它不能是未定义的,因此它会自动将 foo 的类型缩小到仅 string

如果您想让它产生错误,您必须将myList 输入为Array<string | undefined>

let myList: Array<string | undefined> = require('something')

let foo: string | undefined = myList[7]
console.log(foo);
foo.includes('') // Error
foo.length // Error

如果您希望 TypeScript 了解访问数组末尾之后将导致 undefined,请使用 tuple type instead:

let myList: [string, string] = require('something')
let foo = myList[7]

然后foo 被键入为undefined,因为它超过了数组的长度。

如果你事先不知道数组有多少元素,让 TypeScript 抛出你想要的错误的最简单方法就是将数组输入为Array&lt;string | undefined&gt;,因为访问数组的任何数字索引都可能产生一个字符串或未定义,尽管数组的自身属性值都是字符串。

【讨论】:

虽然它会起作用,但我不想要这个,因为它没有任何意义:myList 将永远只包含字符串 只有越界访问(myList[n] 其中n &gt;= myList.length)会导致元素未定义 如果它只包含字符串,那么为什么要将foo 输入为string | undefined?那是不准确的。 因为越界访问,不知道7(或其他数字)是否小于数组长度 听起来 OP 想要在 TS4.1 中实现的“pedantic index signatures”。

以上是关于在 Typescript 中使数组元素可以为空的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 5 迁移中使列不可为空

Typescript,Angular4:刷新浏览器后数组为空

如何在 TypeScript 中使装饰器类型安全?

如何在mysql(laravel)中使varchar可为空且唯一

在 TypeScript 中使泛型参数的顺序变得多余?

在 TypeScript 中获取 JSON 数组的最后一个元素