这篇文章是关于TypeScript中的类型断言,它与其他语言中的类型转换有相似之处,都是通过as运算符执行的。类型断言类型断言允许我们覆盖TypeScript为存储位置计算的静态类型,这对于解决类型系统的限制很有用。类型断言类似于其他语言中的类型转换,但它们不会引发异常并且不会在运行时执行任何操作(它们会静态地执行一些小的检查)。constdata:object=['a','b','c'];//(A)//@ts-ignore:Property'length'doesnotexistontype'object'.data.length;//(B)断言。equal((dataasArray).length,3);//(C)在A行,我们将Array的类型扩展为object。在B行中,我们看到此类型不允许访问任何属性。在C行中,我们告诉TypeScript数据是一个带有类型断言的数组(运算符as)。现在可以访问属性.length。类型断言是最后的手段,应该尽可能避免。他们(暂时)移除了静态类型系统为我们提供的安全网。请注意,在A行中,我们还通过类型注释覆盖了TypeScript的静态类型。这种覆盖方式比类型声明安全得多,因为你可以做的事情少了很多。TypeScript类型必须可分配给带注释的类型。(1)类型断言的替代语法TypeScript有另一种类型断言的“尖括号”语法:>data此语法已过时且与ReactJSX代码(在.tsx文件中)不兼容。(2)示例:声明接口为了访问任意对象obj的属性.name,我们暂时将obj的静态类型改为Named(A行和B行)。interfaceNamed{name:string;}functiongetName(obj:object):string{if(typeof(objasNamed).name=='string'){//(A)return(objasNamed).name;//(B)}return'(Unnamed)';}(3)示例:声明索引签名在下面的代码中,我们在A行使用类型断言作为Dict,以便我们可以访问值为推断类型对象的属性。即,推断出的静态类型对象被静态类型Dict覆盖。typeDict={[k:string]:any};functiongetPropertyValue(dict:unknown,key:string):any{if(typeofdict==='object'&&dict!==null&&keyindict){//%inferred-type:objectdict;//@ts-ignore:元素隐式具有类型'any'因为//类型'string'的表达式不能与索引类型'{}'一起使用。//在类型“{}”上找不到参数类型“string”的索引签名。dict[key];return(dictasDict)[key];//(A)}else{thrownewError();}}类型断言相关的构造(1)非空断言操作符(后缀!)如果value的类型是包含未定义或空类型,非空声明运算符(或非空声明运算符)将从联合中删除这些类型。我们告诉TypeScript:“这个值不能是undefined或null。“因此,我们可以执行被这两个值的类型阻止的操作,例如:consttheName='Jane'as(null|string);//@ts-ignore:Objectispossibly'null'.theName.length;assert。equal(theName!.length,4);//OK(2)例子——Maps:.get()after.has()在使用Map方法.has()之后,我们知道Map有给定的键。不幸的是,.get()的结果没有反映这一点,这就是为什么我们必须使用空断言运算符:functiongetLength(strMap:Map,key:string):number{if(strMap.has(key)){//Waresurexisnotundefined:constvalue=strMap.get(key)!;//(A)returnvalue.length;}return-1;}因为strMap的值永远不会是undefined的,我们可以通过.get()未定义以检测缺失的Map条目(A行):functiongetLength(strMap:Map,key:string):number{//%inferred-type:string|undefinedconstvalue=strMap.get(key);if(value===undefined){//(A)return-1;}//%inferred-type:stringvalue;returnvalue.length;}(3)固定值断言如果th启用了严格的属性初始化,有时需要告诉TypeScript我们确实初始化了某些属性——即使它认为我们不需要。这是一个TypeScript抛出错误的示例,即使它不应该抛出错误:/assignedintheconstructor.y:number;constructor(){this.initProperties();}initProperties(){this.x=0;this.y=0;}}如果我们在A行和B行中使用“”(感叹号),错误就会消失:classPoint2{x!:number;//(A)y!:number;//(B)constructor(){this.initProperties();}initProperties(){this.x=0;这个.y=0;}}