首页 > 其他分享 >TypeScript的类型谓词与控制流分析

TypeScript的类型谓词与控制流分析

时间:2024-07-10 12:26:30浏览次数:11  
标签:TypeScript string 控制流 ts value source 谓词 类型

目录

ts封装类型判断的问题

在union.d.ts 中 全局声明一个 DataType

declare type DataType =
  | "RegExp"
  | "Object"
  | "Array"
  | "Function"
  | "String"
  | "Boolean"
  | "Number"
  | "Void"
  | "Null"
  | "Undefined";

然后在utils文件里封装一个用于判断类型的函数

/**
 * @description 判断値的类型
 * @param {any} value   要检查的值
 * @param {DataType} type  要检查的类型
 * @returns Boolean
 */
export function isType(value: any, type: DataType) {
  if (type === "Void") {
    return value === null || value === undefined;
  }
  //Object 是一个构造函数,直接调用Object.toString,会在原型链上查找,而会先找到Function.prototype,而Function.prototype.toString()的作用不是用来检查类型的
  // 而Object.prototype 是通过 new Object() 创造的实例的原型
  //call:是Function.prototype 的方法,改变this
  const res = Object.prototype.toString.call(value);
  //[object Null] 、 [object Number]等
  return res === `[object ${type}]`;
}

然后我准备封装一个用于过滤对象属性的方法,此时用到了 isType,这时问题就出来了。

export function getFilterObj(
  source: Record<string, any>,
  exclude: string | string[]
) {
  if (isType(exclude, "String")) {
  /** ts报错  exclude 类型“string | string[]”上不存在属性“split”。 
  *   由于此处exclude依然可能是 string[] 类型,所以不能用字符串的方法。
  */
    const { [exclude]: omitted, ...rest } = source;
    return rest;
  } else if (isType(exclude, "Array")) {
  ...
  }
}

我自己封装的方法,ts在外部无法得知value是什么类型,因为返回值是Boolean类型。

类型谓词

类型谓词是一个特殊的函数签名,它在返回布尔值的同时,还告诉TypeScript在函数返回true时,某个参数的具体类型。这是通过在函数签名中使用 参数名 i s \color{orange}is is 目标类型 来实现的。
在返回值为 true 时,额外传递一些信息给调用者

/** 类型谓词 value is string */
// 返回值为true时,形参类型为string 类型
function isString(value: any): value is string {
  return typeof value === "string";
}


function getName(source: string | string[]) {
  if (isString(source)) {
  // 类型校验通过,source为string 类型
    source.split("");
  }
}

但我们注意到,typeof 也可以ts校验通过

function getName(source: string | string[]) {
 if (typeof source === "string") {
  // 类型校验通过,source为string 类型
    source.split("");
  }
}

这里提到一点,就是 js 是运行时执行的,也就是说js的代码在编译时无法得知 source是什么类型,而ts是编译时执行的,而在编译时,source的类型就是自己写定的 string|string[] 类型。

TypeScript的“控制流分析”

但之所以ts最终校验通过,是因为 TypeScript的“控制流分析”,当你在TypeScript代码中使用 if (typeof source === “string”) { … } 这样的条件语句时,TypeScript的类型检查器(Type Checker)会利用这个条件来推断在条件块内部 source 变量的类型。

这是TypeScript的“控制流分析”(Control Flow Analysis)功能的一部分。 T y p e S c r i p t 的类型检查器会分析代码中的条件语句、循环等结构 \color{orange} TypeScript的类型 检查器会分析代码中的条件语句、循环等结构 TypeScript的类型检查器会分析代码中的条件语句、循环等结构,并根据这些结构中的条件来推断变量的类型。在这个例子中,当TypeScript看到 if (typeof source === “string”) { … } 时,它会在条件块内部将 source 的类型推断为 string,即使这个检查实际上是在运行时进行的。

这种类型推断只在语句内部有用

标签:TypeScript,string,控制流,ts,value,source,谓词,类型
From: https://blog.csdn.net/Caoshuang_/article/details/140319010

相关文章

  • TypeScript笔记(一)
    一、TypeScript=Type+JavaScript  在JS基础上,为JS增加了类型支持。TS属于静态类型的编程语言,在编译期间做类型检查,可以在代码编写期间发现问题,减少调试时间。TS相比JS的优势:1、更早的发现错误,减少调试时间;2、代码提示;3、提升可维护性;4、ECMAScript;5、TS有类型推断......
  • zustand Auto Generating Selectors/ts-pattern/swr/TypeScript在monorepo项目中实现
    zustandAutoGeneratingSelectorshttps://docs.pmnd.rs/zustand/guides/auto-generating-selectorsts-pattern替换匹配组件代swrTypeScript在monorepo项目中实现即时更新https://colinhacks.com/essays/live-types-typescript-monorepomonorepodocker项目名:my-project......
  • C语言控制流练习题
    当用户输入5的时候,使用嵌套循环产生下列图案(5行美元符号,每行递增一个字符#include<stdio.h>intmain(void){intline;//输入行数scanf("%d",&line);inti;for(i=1;i<=line;i++)//从每行开始打印{for(intj=1;j<=i;j++)//每一行需要打印数{......
  • typescript 进阶(一)
    前言本文主要记录个人在使用typescript时的一些用法,介绍typescript。建议在阅读前先了解typescript的基础语法。互斥键的类型在ts官网的联合类型文档中有这样一种情况:typeShape=|{kind:"circle";radius:number}|{kind:"square";x:number}|{......
  • TypeScript使用
    检查TypeScript配置:确保您的Vue项目已正确配置TypeScript。您可以检查是否安装了@vue/cli-plugin-typescript插件,并且tsconfig.json文件配置正确。类型定义:确保您正确定义了变量、函数和组件的类型。在Vue组件中,可以使用TypeScript的类型保护帮助我明确变量的类型在T......
  • TypeScript中,如何利用数组生成一个联合类型
    本文由ChatMoney团队出品在开发中我们常常会遇到这样一个问题,代码如下:constarr=["a","b","c","d","e","f","g","h","i","j","k","l&qu......
  • TypeScript中,如何利用数组生成一个联合类型
    本文由ChatMoney团队出品在开发中我们常常会遇到这样一个问题,代码如下:constarr=["a","b","c","d","e","f","g","h","i","j","k","l&qu......
  • TypeScript一些特性让代码更优雅
    TypeScript不仅仅是JavaScript的类型超集,它还提供了一系列强大的高级特性,可以显著提高代码的质量和可维护性,掌握TypeScript的这些高级功能,不仅可以让你的代码更加健壮,还能大大提升你的开发效率。赶紧来看看吧!一、深入理解TypeScript的高级类型推断TypeScript的类型推断系......
  • [TypeScript 学习笔记] 1. 日常类型
    TypeScript类型基础类型类型解释string用于文本字符串number用于数字(整数和浮点数)boolean布尔值,可以是true或falsenull表示缺少值的空对象指针undefined表示未定义的值void表示没有任何返回值的函数never表示永远不会返回的函数任意......
  • 【 ARMv8/ARMv9 硬件加速系列 3.5.1 -- SVE 谓词寄存器有多少位?】
    文章目录SVE谓词寄存器(predicateregisters)简介SVE谓词寄存器的位数SVE谓词寄存器对向量寄存器的控制SVE谓词寄存器位数计算SVE谓词寄存器小结SVE谓词寄存器(predicateregisters)简介ARMv9的ScalableVectorExtension(SVE)引入了谓词寄存器(PredicateR......