TypeScript类型推论(Type Inference)

要完全理解类型推论需要完整理解类型上下文,并且理解TS对于是否可以使用类型推论是基于静态分析完成的。
上下文类型应用在许多地方。常见的例子包括函数调用的参数赋值的右手端位置类型断言对象和数组的成员,和返回语句。上下文类型还充当最佳公共类型中的候选类型。
TS中需要为每个JS名字规定类型,而名字出现在对应的上下文中则会自动获得类型,若没有对应的上下文,这个名字则会自动获得类型any。

名字:通过声明语句声明的名字,例如var、let、const、function a() {}、class A {}、import A from ‘.a’、函数参数等,都会在JS环境中添加一个名字,而TS可以给这个名字指定类型。

在JS中名字的声明是可以在上面提到的常见例子指定的位置,函数参数调用、赋值右手端位置、对象数组成员、返回语句。

函数调用的参数

interface Cb {(a: number): void;
}
interface Fn {(cb: Cb): void;
}const fn: Fn = function (cb) {}fn(function (a) { // 这里a的类型是numberconsole.log(a + 1)
})

因为fn这个名字是类型Fn,而Fn类型的入参是类型Cb,所以在fn使用匿名函数作为入参调用的时候TS可以知道这个匿名函数对应的位置是类型Cb,换句话说匿名函数当前的类型上下文是Cb。而Cb要求入参是number类型,所以推断出匿名函数的参数a是number类型。

赋值的右手端位置

interface Cb {(a: number): void;
}const fn: Cb = function (a) {console.log(a + 1)
}

fn是类型Cb,因为Cb要求入参是number类型,所以TS推断出对应位置匿名函数的入参是number类型。

对象和数组的成员

interface Cb {(a: number): void;
}
interface Obj {fn: Cb
}
const obj: Obj = {fn: function (a) {console.log(a + 1)}
}

obj是类型Obj,而Obj具有属性fn是类型Cb。因为Cb要求入参是number类型,所以TS推断出对象obj.fn右手端对应位置匿名函数的入参是number类型。

返回语句

interface Cb {(a: number): void
}interface Fn {(): Cb
}const fn: Fn = function () {return (a) => {console.log(a + 1)}
}

在这例子里,返回的匿名函数获得类型上下文Cb,而Cb要求入参是number,所以匿名函数的入参被推断出是number类型。

上面的几种类型都可以认为名字出现在了赋值的右手端,而被复制的名字可以给这个值提供对应的类型上下文。

类型断言

interface Fn {(a: number): void;
}const fn = function (a) {console.log(a + 1);
} as Fn;

在这里匿名函数赋值给变量fn而fn本身是没有类型的,所以没办法推断匿名函数的入参a的类型,但是我们使用类型给这个匿名函数指定了类型上下文Fn,让TS具有了推算参数a的依据,得出参数a是number类型。

小结

类型推断起作用的条件是名字出现在对应的上下文位置,而这个上下文可以通过赋值操作的左手端提供,也可以使用类型断言直接提供。这样TS可以根据对应的类型推断出对应变量的类型。

一些意外

interface Fn {(a: number): void;
}function fn(a) {}let a: Fn = fn

在这个例子里,TS无法推断出函数fn的参数a是number类型,因为赋值操作提供的类型上下文在右手端,而fn这个函数声明的位置,并不是右手端。对应的右手端位置并不是函数声明,而是函数声明的引用。所以TS无法静态分析出fn中a的类型。
还有一个原因是fn的使用并不唯一,在这里我们将fn赋值给Fn类型的变量a,我们完全可以将它再赋值给Fn1类型的变量b,所以这种情况下fn中a的类型是由运行时决定的,无法静态分析出来。

interface Fn {(a: number): void;
}function fn(a) {}let a: Fn = fninterface Fn1 {(a: number): void;
}let b: Fn1 = fn

这里Fn1要求入参a的类型是string,所以fn的入参a既可能是number也可能是string,只有运行这个函数的时候才能确定知道参数a是什么类型。所以在这个例子中a会自动获得隐式类型any。

进行如下修改:

interface Fn {(a: number): void;
}let a: Fn = function fn(a) {}

在这里fn是一个表达式,并不会再当前环境中新建一个名字fn,换句话说这个fn不会再用在别的地方,并且a这个名字直接出现在了右手端对应位置,所以这个fn函数可以得到类型上下文Fn,从而推断出参数a的类型是number。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4个万无一失的技巧让您开始使用JBoss BRMS 6.0.3

上周,红帽发布了标记为6.0.3的JBoss BRMS的下一版本,已订阅的用户可以在其客户门户中使用。 如果您对该版本的新增功能感到好奇,请在客户门户网站上在线查看版本说明和其余文档 。 我们正在寻找一些简单的方法来开始使用此新版本&#xff0…

统一命名规则

1. #define 保护 所有头文件都应该使用 #define 防止头文件被多重包含, 命名格式当是:<PROJECT>_<PATH>_<FILE>_H_ 项目 SkinTK中的头文件 SkinTK/SkinTK/targetver.h 可按如下方式保护: #ifndef SKINTK_SKINTK_TARGETVER_H_ #define SKINTK_SKINTK_TARGETVE…

中国移动MM7 API用户手册(七)

4.4 VASP接收状态报告&#xff08;上行业务&#xff09;当VASP在发送MM7SubmitReq给MMSC时设置需要发送状态报告的请求为true时&#xff0c;MMSC在收到MM7SubmitReq后&#xff0c;会发送状态报告给VASP&#xff0c;此时VASP可以进行接收。接收方式和接收传送消息一样&#xff…

如何仅通过CSS实现多行文本超长自动省略号

在CSS中&#xff0c;我们可以通过下面的样式实现DIV元素中文本超长后自动截断并以省略号结尾&#xff1a; overflow: hidden;word-break: normal;text-overflow: ellipsis; text-overflow: ellipsis是实现文本截断后以省略号结尾的关键样式&#xff0c;但问题是如果添加该样式则…

带有Angular JS的Java EE 7 – CRUD,REST,验证–第2部分

这是Angular JS承诺的Java EE 7的后续版本–第1部分 。 花了比我预期更长的时间&#xff08;找到时间来准备代码和博客文章&#xff09;&#xff0c;但是终于到了&#xff01; 应用程序 第1部分中的原始应用程序只是带有分页的简单列表&#xff0c;以及提供列表数据的REST服务…

Chrome不显示OPTIONS请求的解决方法2021版chrome90

在chrome90上之前展示跨域请求预检请求的方法失效了&#xff1a; 在chrome地址栏总输入 chrome://flags/#out-of-blink-cors 将其设置为Disabled后重启浏览器 在chrome://flags找不到选项out-of-blink-cors。取而代之的是chrome将预检请求放到了控制台网络面板的 OTHER 面板中。…

安装CentOs 5.5后无法显中文(中文乱码)

症状&#xff1a;在使用CentOS 系统时&#xff0c;安装的时候可能你会遇到英文的CentOS系统&#xff0c;在这中情况下安装CentOS系统时是默认安装&#xff08;即英文&#xff09;。安装完毕后&#xff0c;上网出现的却是中文乱码。 解决方法&#xff1a; 到CentOs资源网站上去找…

粗读《构建之法》后的思考和收获

利用出差的空挡&#xff0c;快速阅读了一下邹欣老师的《构建之法》一书。对我校软件工程的教学改革确实有很多值得参考的地方&#xff0c;强调实践环节和社会实际工作流程的结合&#xff0c;而不是为了实验而实验。 在阅读过程也有一些问题。 问题1&#xff1a;MSF中强调人员的…

SVG实现波浪效果

SVG实现波浪效果 svg path&#xff1a;C 贝塞尔曲线绘制波浪形状 A 绘制圆弧形 svg animate&#xff1a;制作波浪动画&#xff0c;为了波浪动画效果自然&#xff0c;设置values关键点       attributeName&#xff1a;变化属性名 dur&#xff1a;动画时间 repeatCount&a…

允许同站跨域Nginx配置方案

基于目前前后端分离的趋势和微前端解决方案&#xff0c;并且很多web服务部署在Nginx服务器上&#xff0c;那么因为前后端分离导致的跨域问题需要迫切得到解决。因为是否允许跨域的因素有协议、域名、端口&#xff0c;只要有一个不一致就算跨域。大部分需求要求一个一级域名下所…

使用WildFly 8在Java EE7中自举Apache Camel

从Camel版本2.10开始&#xff0c;支持CDI&#xff08;JSR-299&#xff09;和DI&#xff08;JSR-330&#xff09;。 这为在Java EE容器中以及独立Java SE或CDI容器中开发和部署Apache Camel项目提供了新的机会。 是时候尝试一下并熟悉它了。 骆驼到底是什么&#xff1f; 骆驼是…

Larbin源代码分析[6]LARBIN中线程处理类

一 线程类 larbin下的线程操作类&#xff0c;主要在mypthread.h中定义&#xff0c;实质上是利用宏定义&#xff0c;封装了pthread.h中的系统调用。 一个进程可以有多个线程&#xff0c;每个线程都有自己的处理流程。 二 具体实现 typedef void* (*StartFun) (void *); void sta…

好东西要分享

目录 矢量图标库$\text{pic}$图论神器$\text{bzoj}$离线题库打字速度表情包PPP矢量图标库 个人jio的这个阿里巴巴矢量图标库蛮不错的 上面这张就是去上面的网站找的。 $\text{pic}$ 来wallpaper abyss找点好康的图片吧。 图论神器 画图 $\text{bzoj}$离线题库 $\text{bzoj}$离线…

Vue2.0 全家桶开发的网页应用(参照吾记APP)

github链接 借鉴吾记APP&#xff0c;使用 vue2.0 vue-router vuex 为主要技术栈&#xff0c;elementui做为ui框架&#xff0c;多模块 spa 模式&#xff0c;webpack2.0 负责模块打包&#xff0c;gulp 负责处理静态资源打包、压缩&#xff0c;欢迎打赏star&#xff01;&#xff…

【antd】输入控件的思想

antd对于form中输入控件的抽象十分简单&#xff0c;只要能接收value和onChange属性的组件都可以成为Form.Item的子组件&#xff0c;为Form对应的字段提供值。对于输入控件的抽象我认为这已经达到了极致&#xff0c;事件&#xff08;onChange&#xff09;产生值&#xff08;valu…

Java EE 7批处理和魔兽世界–第1部分

这是我在上一个JavaOne上的会议之一。 这篇文章将扩展主题并使用Batch JSR-352 API进入一个实际的应用程序。 此应用程序与MMORPG 魔兽世界集成。 由于JSR-352是Java EE世界中的新规范&#xff0c;所以我认为许多人不知道如何正确使用它。 确定本规范适用的用例也可能是一个挑…

div+css 你知道多少?值得一看

DIVCSS是网站标准&#xff08;或称“WEB标准”&#xff09;中常用术语之一&#xff0c;divcss 是一种网页的布局方法&#xff0c;这一种网页布局方法有别于传统的HTML网页设计语言中的表格&#xff08;table&#xff09;定位方式&#xff0c;可实现网页页面内容与表现相分离。X…

学习笔记-AngularJs(十)

前面一直在说自定义指令&#xff0c;但是却一直没有一次系统地去了解&#xff0c;现在需要我们一起来学习如何去使用自定义指令&#xff0c;去丰富html标签、属性&#xff0c;实现多元化、多功能的标签&#xff08;或是属性&#xff09;。辣么&#xff0c;啥是指令&#xff1f;…

WildFly 9 –别希望您的控制台像这样!

每个人都可能听到这个消息。 周一发布了第一个WildFly 9.0.0.Alpha1版本。 您可以从wildfly.org网站上下载它&#xff0c;最大的变化是它是由一个新的功能配置工具构建的&#xff0c;该工具位于现在单独的核心发行版中&#xff0c;并且还包含一个新的Servlet发行版 &#xff08…

磁盘性能 -- IOPS 和 吞吐量 说明

一. Wikepedia上有关IOPS 的说明链接如下&#xff1a;http://en.wikipedia.org/wiki/IOPSIOPS (Input/Output OperationsPer Second, pronounced i-ops) is a common performance measurement used to benchmark computer storage devices like harddisk drives (HDD), solid s…