Narrowing概念:字面意思是缩小,可以理解为细化或者您觉得更好的代名词。

TS官方在这里做了很详细的说明,文字较多,简单以图片概括:

typeof  type guards 类型防护过程,可以通过 typeof 检测出大部分类型并对比预设类型,如:

  • "string"
  • "number"
  • "boolean"
  • "symbol"
  • "undefined"
  • "object"
  • "function"

但是对于特殊的对象,比如 null ,typeof 就无能为力了,因为 typeof null === 'object'。看个例子:

function printAll(strs: string | string[] | null) {
  if (typeof strs === "object") {
    for (const s of strs) {   //for of 遍历数组中的元素

      //  Object is possibly 'null'.Object is possibly 'null'.

      console.log(s);
  }
  } else if (typeof strs === "string") {
    console.log(strs);
  } else {
    // do nothing
  }
}
 
布尔值运算
因为对下列这些对象进行布尔运算返回都是 false : 
  • 0
  • NaN
  • null
  • undefined
  • ""

所以上面的例子可以先对 null 进行判断然后执行后面的逻辑

function printAll(strs: string | string[] | null) {
  if (strs && typeof strs === "object") {
    for (const s of strs) {   //for of 遍历数组中的元素

      // strs 如果是null则跳过这个分支

      console.log(s);
  }
  } else if (typeof strs === "string") {
    console.log(strs);
  } 
}
 
思考以下两个方法有何不同?
 
function printAll(strs: string | string[] | null) {
  if (strs) {
    if (typeof strs === "object") {
      for (const s of strs) {
        console.log(s);
      }
    } else if (typeof strs === "string") {
      console.log(strs);
    }
  }
}
 
function anotherPrintAll(strs: string | string[] | null) {
  if (strs !== null) {
    if (typeof strs === "object") {
      for (const s of strs) {
        console.log(s);
      }
    } else if (typeof strs === "string") {
      console.log(strs);
    }
  }
}
 
  使用 in 操作符进行类型缩小
js中使用in操作符可以判单一个对象是否拥有某个属性,ts 也将in作为缩小类型判断的方式。
比如在一个联合类型中,可以这样判断 'value' in x,
x可能是 type Animal = Fish | Bird, value 表示 x 中的某一个字面量(可能是Fish或者Bird)
 
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
  if ("swim" in animal) {
    return animal.swim();
  }
  return animal.fly();
}
 
使用类型谓词
有时候我们希望从更多角度控制类型的检测,定义一个自定义的类型防护,即定义一个返回类型的方法就是一个类型谓词。
例如:
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}
pet is Fish 就是一个类型谓词。定义一个类型谓词的方式:参数名称 is 类型名称,参数名称必须是当前方法的一个参数。
任何时候,只要isFish携带参数调用了,如果原始类型兼容,TypeScript会将该变量缩小到该特定类型。
例如:
 
let pet = getSmallPet();
if(isFish(pet)) {
  pet.swim();
} else {
  pet.fly();
}
 
ts可以在if分支处得知pet是一条能游的Fish,当然了在else分支处pet被当作一只能飞的Bird。
当然了,你可以使用isFish这个类型防护去过滤一个包含了飞鸟与鱼的数组,最后得到一个尽是鱼的数组。
例如:
 
const zoo: (Fish | Bird)[] = [getSmallPet(), getSmallPet(), getSmallPet()];
const underWater: Fish[] = zoo.filter(isFish)

最新文章

  1. Python ORM Storm 源码修改
  2. android学习之RadioButton和CheckBox
  3. Java多线程学习(转载)
  4. 第8课 goto 和 void 分析
  5. OpenSuse13.2安装CUDA Toolkit 7.5
  6. HTML中关于图像和表格,链接等的知识
  7. fzu1969 GCD Extreme 类似于uva10561
  8. Django创建应用、模型、配置后台自动管理
  9. WPF水珠效果按钮组
  10. vue config.js配置生产环境和发布环境不同的接口地址问题
  11. Oracle学习笔记之触发器
  12. 背水一战 Windows 10 (112) - 通知(Badge): application 的 badge 通知, secondary 的 badge 通知, 轮询服务端以更新 badge 通知
  13. Tmk吃汤饭
  14. SQL Server 中如何移动tempdb到新的位置
  15. 牛客小白月赛6-E对弈-简单搜索
  16. 【SqlServer】SQL Server的常用函数
  17. iOS开发如何学习前端(2)
  18. shiro标签的使用
  19. export命令详解
  20. 【ML】概率图模型

热门文章

  1. Jedis操作五种不同的类型的数据
  2. MicroK8S 安装 修改IP 设置镜像加速 升级 卸载等
  3. 20 个 .NET 6 新增的 API
  4. OpenGL ES2 缩放移动
  5. 去除爬虫采集到的\xa0、\u3000等字符
  6. [BUUCTF]PWN——ciscn_2019_ne_5
  7. Python变量的作用域在编译过程中确定
  8. 「Python实用秘技03」导出项目的极简环境依赖
  9. CF250A Paper Work 题解
  10. CF753A Santa Claus and Candies 题解