typescript怎么加号(Typescript中的as、问号与感叹号详解)
typescript怎么加号
Typescript中的as、问号与感叹号详解1、as关键字表示断言在Typescript中,表示断言有两种方式。一种是扩号表示法:
let someValue: any = "this is a string"; let strLength: number = (someValue).length;
另一种使用as关键字:
let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
问号表示可选的属性,一般用于属性定义,如,用于接口时:
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig) { if (config.color) { 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'
这个比较也验证了上述的结论。
问号(?)用于属性读取
问号用于属性读取,主要有两个场景:一是读取数组元素(如下面的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"]; // var b = node[i].data.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"]; // var b = node[i]?.data?.class; // var b = node[i].data.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"]; // var b = (node[i] as VNode).data?.class // var b = node[i]?.data?.class; // var b = node[i].data.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、问号与感叹号详解的文章就介绍到这了,更多相关Typescript中as、问号与感叹号内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- typescript开发后端(教你使用webpack打包编译TypeScript代码)
- typescript获取属性名(TypeScript 中如何限制对象键名的取值范围)
- react新手指引页面编写(React+TypeScript进行项目构建案例讲解)
- typescript使用技巧(深入理解typescript中的infer关键字的使用)
- TypeScript定义接口(interface)案例教程(TypeScript定义接口interface案例教程)
- 数据类型typescript知多少(一文了解TypeScript数据类型)
- typescript技巧(为什么TypeScript的Enum会出现问题)
- typescript怎么加号(Typescript中的as、问号与感叹号详解)
- 《无敌破坏王2》 不聊彩蛋,聊聊我从动画里看到的现实那些事儿(无敌破坏王2不聊彩蛋)
- 《寄生虫》 三观不正 人类悲欢从来不相通,感同身受也并非本能(寄生虫三观不正)
- 这部动漫中的女孩子,可比101女孩更加励志(这部动漫中的女孩子)
- 《白狐的人生》热拍 贾征宇偶像包袱难自弃 图(白狐的人生热拍)
- 七夕取消了,牛郎织女没做核酸七夕已经取消(牛郎织女没做核酸七夕已经取消)
- 网友抵制 多地取消 夏日祭 为何惹众怒(网友抵制多地取消)
热门推荐
- pyqt5数据模型(PyQt5实现简单数据标注工具)
- springboot如何解析vue登录参数(SpringBoot + Vue 项目部署上线到Linux 服务器的教程详解)
- serv-u的默认端口号(Serv-U 8.0 服务器中文乱码问题的解决)
- 怎么用css设计边框(单元素利用css实现多重边框效果示例代码)
- dockerpull下来的容器存放位置(详解docker pull下来的镜像存储在哪里)
- jenkins 设置gitlab(jenkins+gitlab+nginx部署前端应用实现)
- php7 入门(php7新特性的理解和比较总结)
- phpstudy 目录浏览宽度(JspStudy如何设置PHP根目录可编辑)
- sqlserver追加主键(sqlserver主键自增的实现示例)
- dedecms有哪些功能(织梦DedeCMS v5.7全文检索使用说明sphinx)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8