脚本宝典收集整理的这篇文章主要介绍了TypeScript学习笔记之类型窄化篇,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
TS最好用的地方就是强类型,随之而来的就是类型窄化,摸鱼的时候顺道总结下.
TyPEScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型
Example:
let x = [0, 1, null] // number let x = Math.random() < 0.5 ? 100 : "helloword" // number|string let x: Animal[] = [new Rhino(), new Elephant(), new Snake()]; // Rhino | Elephant | Snake
如果没有找到最佳通用类型的话,类型推断的结果为联合数组类型
联合类型和类型守卫
Example:
// 联合类型 type Types = number | string function typeFn(type: Types, input: string): string { // 如果这样写就需要判断type的类型 }
可以直接赋值类型推断
let x:number|string = 1 x="tiedan"
如果不判断会报错
function typeFn(type: number | string, input: string) { // 报错 运算符+号不能应用于 string return new Array(type + 1).join("") + input }
所以还得判断
function typeFn(type: number | string, input: string) { // 类型守卫 if (typeof type === 'number') { return new Array(type + 1).join(" ") + input } return type + input }
类型的窄化就是根据判断类型重新定义更具体的类型
那么问题来了学这玩意干嘛? js不香吗?
个人观点:
使用 TypeScript 可以帮你降低 JavaScript 弱语言的脆弱性,帮你减少由于不正确类型导致错误产生的风险,以及各种 JavaScript 版本混杂造成错误的风险。
TypeScript 只是把高级语言的强类型这个最主要的特征引入 JavaScript ,就解决了防止我们在编写 JavaScript 代码时因为数据类型的转换造成的意想不到的错误,增加了我们排查问题的困难性。
typeof的类型守卫:
注意: typeof null 等于 object
因此:
function strOrName(str: string | string[] | null) { if (typeof str === 'object') { for (const s of str) { // 报错 因为str有可能是null console.LOG(s) } } else if (typeof str === 'string') { console.log(str) } else { //...... } }
js的真值表很复杂, 除以下的是false其余的都是真。
0 NAN "" 0n // 0的bigint版本 null undefined
避免null的错误可以利用真值窄化
// 利用真值判断 if (str && typeof strs === 'object') { for (const s of strs) { console.log(s) } }
或者这样也行
function valOrName(values: number[] | undefined, filter: number): number[] | undefined { if (!values) { return values } else { return values.filter(x => x > filter) } }
小结: 真值窄化帮助我们更好的处理null/undefined/0 等值
想等性窄化就是利用 ===、 !== 、==、and、!= 等运算符进行窄化
Example1:
function strOrNum(x: string | number, y: string | boolean) { if (x === y) { // string } else { // string|number } }
Example2:
function strOrName(str: string | string[] | null) { if (str !== null) { if (typeof str === 'object') { for (const s of str) { console.log(s) // [] } } else if (typeof str === 'string') { console.log(str) // string } else { // ..... } } }
Example3:
interface Types { value: number | null | undefined } function valOrType(type: Types, val: number) { // null和undefined 都是false 只能是number if (type.value != null) { type.value *= val } }
in是检查对象中是否有属性,现在充当了一个 "type Guard" 的角色。
Example:
interface A { a: number }; interface B { b: string }; function foo(x: A | B) { if ("a" in x) { return x.a; } return x.b; }
instanceof表达式的右侧必须属于类型 any,或属于可分配给 Function接口类型的类型。
Example:
function dateinval(x: Date | string) { if (x instanceof Date) { // Date } else { // string } }
窄化的本质是重新定义类型
Example:
function example() { let x: string | number | boolean x = Math.random() < 0.5 if (Math.random() < 0.5) { x = 'hello' // string } else { x = 100 // number } return x; // string|number }
Example1:
interface Shape { kind: "cirle" | "square", redius?: number sideLength?: number } // 报错 function getArea(shape: Shape) { return Math.PI * shape.redius ** 2 } // 窄化还是报错 function getArea(shape: Shape) { if (shape.kind === 'cirle') { return Math.PI * shape.redius ** 2 } } // 利用非空断言阔以 function getArea(shape: Shape) { if (shape.kind === 'cirle') { return Math.PI * shape.redius! ** 2 } }
Example2:
interface Circle { kind: "cirle"; redius: number; } interface Square { kind: "square"; redius: number; } type Shape = Circle | Square function getArea(shape: Shape) { if (shape.kind === 'cirle') { // 窄化 return Math.PI * shape.redius ** 2 } } // 或者 function getArea(shape: Shape) { swITch (shape.kind) { case "cirle": return Math.PI * shape.redius ** 2 case "square": return shape.sideLength ** 2 default: const _example: never = shape return _example } }
到此这篇关于TypeScript学习笔记之类型窄化篇的文章就介绍到这了,更多相关TypeScript类型窄化内容请搜索脚本宝典以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本宝典!
以上是脚本宝典为你收集整理的TypeScript学习笔记之类型窄化篇全部内容,希望文章能够帮你解决TypeScript学习笔记之类型窄化篇所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。