typescript高级类型详解(TypeScript中的类型断言详解)
typescript高级类型详解(TypeScript中的类型断言详解)<Array<string>>data该语法已经过时,并且与 React JSX 代码(概 .tsx 文件中)不兼容。TypeScript 对于类型断言有另一种“尖括号”语法:类型断言与其他语言中的类型强制转换有相似之处,但是它们不会引发异常,并且在运行时也不做任何事情(它们确实会静态执行一些少量的检查)。constdata:object=['a' 'b' 'c'];//(A) //@ts-ignore:Property'length'doesnotexistontype'object'. data.length;//(B) assert.equal( (dataasArray<string>).length 3);//(C)在 A 行中,我们把 Array 的类型扩展为
作者: 疯狂的技术宅
转发链接:https://mp.weixin.qq.com/s/RbWZkfuJnlIeydQGaxkFBA
前言本文是关于 TypeScript 中的 type assertions 的,它与其他语言中的类型强制转换有相似之处,并通过 as 运算符执行。
类型断言
类型断言使我们可以覆盖 TypeScript 为存储位置计算的静态类型,这对于解决类型系统的限制很有用。
类型断言与其他语言中的类型强制转换有相似之处,但是它们不会引发异常,并且在运行时也不做任何事情(它们确实会静态执行一些少量的检查)。
constdata:object=['a' 'b' 'c'];//(A)
//@ts-ignore:Property'length'doesnotexistontype'object'.
data.length;//(B)
assert.equal(
(dataasArray<string>).length 3);//(C)
- 在 A 行中,我们把 Array 的类型扩展为 object。
- 在 B 行中,我们看到此类型不允许访问任何属性。
- 在 C 行中,我们用类型断言(运算符 as)告诉 TypeScript data 是一个Array。现在就可以访问属性 .length 了。
类型断言是不得已的方法,应尽可能的避免。他们(暂时)删除了静态类型系统为我们提供的安全网。
注意,在 A 行中,我们还覆盖了 TypeScript 的静态类型,不过是通过类型注释完成的。这种覆盖方式比类型声明要安全得多,因为你可以做的事情少得多。TypeScript 的类型必须能够分配给注释的类型。
类型断言的替代语法TypeScript 对于类型断言有另一种“尖括号”语法:
<Array<string>>data
该语法已经过时,并且与 React JSX 代码(概 .tsx 文件中)不兼容。
示例:声明一个接口为了访问任意对象 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)';
}
示例:声明索引签名
在以下代码中,我们在行 A 用了类型断言 as Dict ,以便可以访问其推断类型为object 的值的属性。也就是说,用静态类型 Dict 覆盖了推断的静态类型object。
typeDict={[k:string]:any};
functiongetPropertyValue(dict:unknown key:string):any{
if(typeofdict==='object'&&dict!==null&&keyindict){
//%inferred-type:object
dict;
//@ ts-ignore:元素隐式具有“any”类型,因为
//类型'string'的表达式不能用于索引类型'{}'。
//在类型“{}”上没有找到参数类型为'string'的索引签名。
dict[key];
return(dictasDict)[key];//(A)
}else{
thrownewError();
}
}
与类型断言相关的构造非空断言运算符(后缀 `!`)
如果值的类型是包含 undefined 或 null 类型的联合,则 non-nullish声明运算符(或 non-null 声明运算符)将从联合中删除这些类型。我们告诉 TypeScript:“这个值不能是 undefined 或 null。”因此,我们可以执行这两个值的类型所阻止的操作,例如:
consttheName='Jane'as(null|string);
//@ts-ignore:Objectispossibly'null'.
theName.length;
theName!.length 4);//OK
示例 – Maps: `.has()` 之后的 `.get()`
使用 Map 方法 .has() 之后,我们知道 Map 具有给定的键。遗憾的是,.get()的结果不能反映这一点,这就是为什么我们必须使用 nullish 断言运算符的原因:
functiongetLength(strMap:Map<string string> key:string):number{
if(strMap.has(key)){
//Wearesurexisnotundefined:
constvalue=strMap.get(key)!;//(A)
returnvalue.length;
}
return-1;
}
由于 strMap 的值永远不会是 undefined,因此我们可以通过检查 .get() 的结果是否为 undefined 来检测丢失的 Map 条目(A 行):
functiongetLength(strMap:Map<string string> key:string):number{
//%inferred-type:string|undefined
if(value===undefined){//(A)
return-1;
}
//%inferred-type:string
value;
returnvalue.length;
}
定值断言
如果打开 strict 属性初始化,有时需要告诉 TypeScript 我们确实初始化某些属性——即使它认为我们不需要这样做。
这是一个例子,尽管 TypeScript 不应这样做,但它仍会报错:
classPoint1{
//assignedintheconstructor.
x:number;
//@ts-ignore:Property'y'hasnoinitializerandisnotdefinitely
//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;
this.y=0;
}
}
推荐TypeScript知识点文章
深入浅出TypeScript在Model中的高级应用
让人眼前一亮的 10 大 TypeScript 项目
拿6个案例讲解TypeScript 知识点「干货」
TypeScript 中的顶级类型:any 和 unknown
1500行TypeScript代码在React中实现组件keep-alive
「TypeScript」详解一个了不起的 tsconfig.json 指南
用TypeScript编写React的优雅实践「干货」
了不起的 TypeScript 入门教程「实践篇」
了不起的 TypeScript 入门教程「基础篇」
TypeScript 常见问题整理(60多个)「上」
TypeScript 常见问题整理(60多个)「下」
深入TypeScript难点梳理讲解
Vue3.0之前你必须知道的TypeScript实战技巧
深入TypeScript难点梳理讲解
Vue3.0之前你必须知道的TypeScript实战技巧
你需要的 React TypeScript 50 条规范和经验
TypeScript详细概括【思维导图】
Vue3.0 尝鲜 Hook TypeScript 取代 Vuex【项目实践】
TypeScript详细概括【思维导图】
「新消息」基于JavaScript/TypeScript 编程环境Deno1.0 即将发布
「干货」一张页面引起的项目架构思考(rax Typescript hooks)
深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】
作者: 疯狂的技术宅
转发链接:https://mp.weixin.qq.com/s/RbWZkfuJnlIeydQGaxkFBA