为什么ab在下面的代码中有不同的类型?

function empty<T>() { return [] as T[] }

const defEmpty = empty()

function test1(abc: number[]|null) {
  const a = abc ?? defEmpty
  const b = abc ?? empty()
}
 

playground,我能看到a: unknown[]b: number[].我本以为他们都是unknown[]型的.

推荐答案

您没有在此处的empty() Call中提供显式泛型类型:

const b = abc ?? empty()

但是TypeScrip可以从表达式中推断出该类型-它知道abcnumber[] | null类型,所以它推断empty调用的类型参数是number(顺便说一下,你可以通过你的链接在操场上看到它,如果你把鼠标悬停在empty()上).所以你的台词基本上变成了:

const b = abc ?? empty<number>();

因此,B也是类型number[].请注意,省略泛型类型参数并不意味着它将变为unknown.

至于类型推断到底是如何工作的--据我所知,目前还没有严格的规范.最后specification version个被存档,不再维护.与这个存档的规范相比,有changes个要分类的推理规则.因此,你所拥有的最好的信息来源是docs,这是相当模糊的.相关的部分被称为"上下文类型",它概括地描述了在许多情况下,TypeScrip能够从上下文推断泛型类型参数,但没有严格地描述它是如何工作的.

然而,这个 case 似乎相当清楚.在左手边的??表达式具有已知类型表达式,因此在右侧使用相同的类型并省略泛型类型参数是有意义的.

Typescript相关问答推荐

Angular 垫页分类和垫排序不起作用

为什么在将条件返回类型的字符串赋给数字时没有类型错误?

为什么ESLint抱怨通用对象类型?

类型断言添加到类型而不是替换

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

如何在使用`Next—intl`和`next/link`时导航

单击并移除for循环中的一项也会影响另一项

使用泛型keyof索引类型以在if-condition内类型推断

Vue SFC中的多个脚本块共享导入的符号

如何以Angular 形式显示验证错误消息

为什么我的条件类型不能像我预期的那样工作?

<;T扩展布尔值>;

使用Redux Saga操作通道对操作进行排序不起作用

为什么ESLint会抱怨函数调用返回的隐式`any`?

将对象的属性转换为正确类型和位置的函数参数

创建依赖函数参数的类型

为什么特定的字符串不符合包括该字符串的枚举?

如何在try 运行独立的文字脚本Angular 项目时修复Visual Studio中的MODULE_NOT_FOUND

如何扩展RxJS?

使用RXJS获取数据的3种不同REST API