对比理解Typescript中的as、问号与叹号
2020/2/21 11:17:50
本文主要是介绍对比理解Typescript中的as、问号与叹号,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
as
关键字表示断言
在Typescript
中,表示断言有两种方式。一种是尖扩号表示法:
let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length; 复制代码
另一种使用as
关键字:
let someValue: any = "this is a string"; let strLength: number = (someValue as string).length; 复制代码
唯一区别是,在JSX
中,尖扩号与JSX
语法冲突,只能使用as
关键字。
问号(?)用于属性定义
准备工作:以下示例可以建立一个optional.ts的文件,然后用
tsc
进行编译。tsc
可以用npm install -g typescript
安装。
//运行以下命令可以在同目录下生成optional.js,有错误时会报错 tsc optional.ts tsc --strictNullChecks optional.ts 复制代码
问号表示可选的属性,一般用于属性定义,如,用于接口时:
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig) { if (config.clor) { console.log(config); } } 复制代码
可选属性的含义是:使用这个属性时,要么这个属性名不存在,要么必须符合属性的类型定义(官方解释)。比如上述createSquare
函数编译时会报error
错误:
error TS2551: Property 'clor' does not exist on type 'SquareConfig'. 复制代码
如果修改createSquare
,将config.color
的值改为undefined
,会怎样?
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig) { config.color = undefined; if (config.color) { console.log(config); } } 复制代码
这时并没有编译报错!明明config.color
定义的是string
类型呀?
即便是添加--strictNullChecks
进行编译,也不会报错。可见,可选属性所定义的类型,并没有被typescript
严格地对待,默认并不检查undefined
。需要注意的是,将上述undefined
改成null
时,普通编译也不报错,--strictNullChecks
编译会报如下错误:
error TS2322: Type 'null' is not assignable to type 'string | undefined' 复制代码
从这句报错中,我们可以得出这样的结论:可选属性等价于一个union
类型,union了undefined
;不加--strictNullChecks
编译时,null
可以赋值给undfined
类型。也就是说,SquareConfig
的定义与下面的代码等价:
interface SquareConfig { color: string|undefined; width: number|undefined; } 复制代码
下面比较一下可选属性与正常属性。再次修改createSquare
,将color
属性修改为正常属性。
interface SquareConfig { color: string; width?: number; } function createSquare(config: SquareConfig) { config.color = undefined; if (config.color) { console.log(config); } } 复制代码
以--strictNullChecks
编译,报错了:
error TS2322: Type 'undefined' is not assignable to type 'string' 复制代码
这个比较也验证了上述的结论。
问号(?)用于属性读取
以下示例都使用
--strictNullChecks
编译
问号用于属性读取,主要有两个场景:一是读取数组元素(如下面的node[i]),二是读取不确定的类型如any
,union
,可选类型(如node[i].data)等。如下例,保存为index.ts
:
interface VNodeData { class?: string; } interface VNode { sel?: string; data?: VNodeData; } function test(node: VNode[]) { let i = 0; var b = node[i].data.class; if(b !== undefined) { console.log(1); } } 复制代码
用tsc --strictNullChecks index.ts
,报错:
error TS2532: Object is possibly 'undefined' 复制代码
下面将一一展示这一行代码var b = node[i].data.class;
修改改后的效果。
1、修改为var b = node[i]?.data.class;
,然后编译。报错:
Object is possibly 'undefined' 复制代码
2、修改为var b = node[i]?.data?.class;
,然后编译。编译通过,查看编译后的对应代码为:
function test(node) { var _a, _b; var i = 0; var b = (_b = (_a = node[i]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b["class"]; if (b !== undefined) { console.log(1); } } 复制代码
摘出来看,var b = node[i]?
表示,如果node[i]
的值为null
或者undefined
,则b
等于undefined
,否则b=node[i]
。
3、修改为var b = (node[i] as VNode).data?.class;
,然后编译。编译通过,查看编译后的对应代码为:
function test(node) { var _a; var i = 0; var b = (_a = node[i].data) === null || _a === void 0 ? void 0 : _a["class"]; if (b !== undefined) { console.log(1); } } 复制代码
此时,使用node[i]
时,Typescript
编译器将不再对其判断是否为null
和undefined
。即:var b = node[i] as VNode
直接会被编成var b = node[i]
。
4、修改为var b = node[i]!.data?.class
,然后编译。编译通过,查看编译后的对应代码为:
function test(node) { var _a; var i = 0; var b = (_a = node[i].data) === null || _a === void 0 ? void 0 : _a["class"]; if (b !== undefined) { console.log(1); } } 复制代码
可见,3和4的编译后代码完全一样,!
的作用此时与as
是等价的。然后,!
只是用来判断null
和undefined
;as
则可用于缩小类型检测范围,仅当as
后面跟的类型是一个非空类型时,两者才等价。如下例中,不能将as
用法改为!
。
interface Cat { action: string; } interface Dog { action: string; } type Animal = Cat | Dog; let action:Animal = {} as Cat; 复制代码
结论
1、as
和!
用于属性的读取,都可以缩小类型检查范围,都做判空用途时是等价的。只是!
具体用于告知编译器此值不可能为空值(null
和undefined
),而as
不限于此。
2、?
可用于属性的定义和读取,读取时告诉编译器此值可能为空值(null
和undefined
),需要做判断。
这篇关于对比理解Typescript中的as、问号与叹号的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-06Package Easy(基于 NSIS 的打包exe安装包工具)使用方法-icode9专业技术文章分享
- 2024-06-06基于 casdoor 的 ELK 开源登录认证解决方案: elk-auth-casdoor-icode9专业技术文章分享
- 2024-05-29Elasticsearch慢查询日志配置
- 2024-05-29揭秘华为如此多成功项目的产品关键——Charter模板
- 2024-05-29海外IDC业务拓展的7大挑战
- 2024-05-29InLine Chat功能优化对标Github Copilot,CodeGeeX带来更高效、更直观的编程体验!
- 2024-05-29CodeGeeX 智能编程助手 6 项功能升级,在Visual Studio插件市场霸榜2周!
- 2024-05-29AutoMQ 生态集成 Apache Doris
- 2024-05-292024年IDC行业的深度挖掘:机遇、挑战与未来展望
- 2024-05-29五款扩展组件齐发 —— Volcano、Keda、Crane-scheduler 等,邀你体验