您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

TypeScript学习笔记之类型窄化篇

51自学网 2022-05-02 21:31:36
  javascript

前言

TS最好用的地方就是强类型,随之而来的就是类型窄化,摸鱼的时候顺道总结下.

类型推论

TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型

Example:

let x = [0, 1, null] // numberlet x = Math.random() < 0.5 ? 100 : "helloword" // number|stringlet x: Animal[] = [new Rhino(), new Elephant(), new Snake()]; // Rhino | Elephant | Snake

如果没有找到最佳通用类型的话,类型推断的结果为联合数组类型

联合类型和类型守卫

Example:

// 联合类型type Types = number | stringfunction typeFn(type: Types, input: string): string {  //  如果这样写就需要判断type的类型}

可以直接赋值类型推断

let x:number|string = 1x="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的类型守卫:

"string""number""bigint" // ES10新增"boolean""symbol" // ES6新增"undefined""object""function"

注意: 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其余的都是真。

0NAN""0n // 0的bigint版本nullundefined

避免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操作符窄化

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窄化

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 | Squarefunction 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类型窄化内容请搜索wanshiok.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持wanshiok.com!


Vue.js $refs用法案例详解
Vue.js slot插槽的作用域插槽用法详解
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1