首页 > 其他分享 >TS中除了这些情况请禁用any

TS中除了这些情况请禁用any

时间:2024-09-15 17:47:20浏览次数:10  
标签:禁用 TS any goodbye unknown 类型 input hello

在TypeScript中,any 类型是一个非常强大的类型。它允许你将一个值当作在JavaScript中一样来处理,而不是在TypeScript中。这意味着它禁用了TypeScript的所有特性,包括类型检查、自动补全和安全性。

const myFunction = (input: any) => {
  input.someMethod();
};

myFunction("abc"); // This will fail at runtime!

在实际项目中,any 可能会造成以下几个问题:

  1. 丧失类型安全性:使用 any 会导致 TypeScript 不再检查你的代码是否存在潜在的错误,这与引入 TypeScript 的初衷背道而驰。
  2. 难以维护:当代码库中充斥着大量的 any 类型时,调试和维护变得更加困难。你无法通过类型系统获得代码的准确信息。
  3. 隐藏错误:因为 any 允许你调用不存在的属性或方法,这可能会导致隐藏的 bug 只有在运行时才暴露出来,而不是在编译时发现。

在大多数情况下,any 类型被认为是bad code。并会使用eslint来避免使用any。然而,有一些情况使用 any 却是正确的选择。

类型参数约束

假设我们要在TypeScript中实现一个ReturnType的工具方法,该方法接受一个函数类型,并返回它的返回值类型。

我们需要创建一个泛型类型,这个泛型类型接受一个函数类型作为其类型参数。如果我们限制自己不使用任何特定的类型(例如any),我们可能会选择使用unknown类型。unknown 是比 any 更加严格和安全的类型。它允许你存储任何类型的值,但在你使用该值之前必须进行类型检查,不能随意调用属性或方法。

type ReturnType<T extends (...args: unknown[]) => unknown> = T extends (...args: unknown[]) => infer R ? R : never;
  • ReturnType: 这里定义了一个泛型类型ReturnType,它接受一个类型参数T。
    类型约束:

  • T extends (...args: unknown[]) => unknown: 这个约束指定T必须是一个函数类型,这个函数接受一个参数列表(每个参数都是unknown类型),并返回一个unknown类型的值。
    条件类型:

  • T extends (...args: unknown[]) => infer R ? R : never: 这是一个条件类型表达式,它使用了infer关键字来推断函数返回的具体类型。

    • infer R: 这部分尝试从满足(...args: unknown[]) => unknown类型的函数中推断出返回类型R。
      ? R: 如果推断成功,那么ReturnType的结果是推断出的返回类型R。
    • : never: 如果推断失败(例如,如果T不是一个函数类型或者函数的返回类型不是unknown),则ReturnType的结果是never类型,表示这个类型不存在任何值。

但一旦我们添加一个参数,它就失效了。提示无法把unknown赋值给string。

实际上,如果我们参数是unknown的话,它确实是生效的。

只接受unknown作为参数的效果显然不是我们想要的。我们希望它对任何函数都有效。这时候就不得不使用any[]作为类型参数约束:

type ReturnType<T extends (...args: any[]) => any> =
  T extends (...args: any[]) => infer R ? R : never;

const myFunction = (input: string) => {
  console.log("Hey!");
};

type Result = ReturnType<typeof myFunction>;

现在它按预期工作了。我们不在乎函数接受什么类型——它可以是任意类型。因为我们本来的目的就是创建一个不严格的类型,所以这是安全的。

从通用函数中返回条件类型

在某些情况下,TypeScript的类型缩小能力可能不足以满足需求。例如,你可能希望创建一个函数,根据条件返回不同的类型。

const youSayGoodbyeISayHello = (
  input: "hello" | "goodbye"
) => {
  if (input === "goodbye") {
    return "hello";
  } else {
    return "goodbye";
  }
};

const result = youSayGoodbyeISayHello("hello");

在这里,result会被推断成"hello" | "goodbye"。但我们传进去的是hello嗄,hello返回的应该就是goodbye。这显然是不准确的。我们可以这样子改造一下:

const youSayGoodbyeISayHello = <
  TInput extends "hello" | "goodbye"
>(
  input: TInput
): TInput extends "hello" ? "goodbye" : "hello" => {
  if (input === "goodbye") {
    return "hello" as TInput extends "hello"
      ? "goodbye"
      : "hello";
  } else {
    return "goodbye" as TInput extends "hello"
      ? "goodbye"
      : "hello";
  }
};

我们为函数的返回类型添加了一个条件类型,它反映了我们的运行时逻辑。通过对结果做类型转换,实现我们想要的结果。但这样子做会有一个弊端,每个类型都要写一次。那有没有更好的方式呢?使用any会显得更通用。

const youSayGoodbyeISayHello = <
  TInput extends "hello" | "goodbye"
>(
  input: TInput
): TInput extends "hello" ? "goodbye" : "hello" => {
  if (input === "goodbye") {
    return "hello" as any;
  } else {
    return "goodbye" as any;
  }
};

如果不使用 any,TypeScript可能无法正确地将条件类型与运行时逻辑相匹配,导致类型错误。

结论

一个问题仍然存在:你应该禁止any吗?答案应该是肯定的。您应该打开ESLint规则,以防止其使用,并且您应该尽可能避免使用它。

然而,有些情况下需要any。他们值得使用eslint-disable来绕过它们。

本文由mdnice多平台发布

标签:禁用,TS,any,goodbye,unknown,类型,input,hello
From: https://www.cnblogs.com/miniwa/p/18415483

相关文章

  • python的subplots 多图处理变模糊
    在使用Python的Matplotlib库中的subplots功能来创建多个子图时,有时可能会遇到图像变得模糊或分辨率降低的问题。这通常是由于几个不同的因素引起的,包括图像尺寸设置、DPI(每英寸点数)设置、保存图像时使用的文件格式和参数等。下面,我将详细解释这些因素,并提供一些改进图像质量......
  • Ubuntu 22.04.5 LTS 发布下载 - 现代化的企业与开源 Linux
    Ubuntu22.04.5LTS(JammyJellyfish)-现代化的企业与开源LinuxUbuntu22.04.5发布,配备Linux内核6.8请访问原文链接:https://sysin.org/blog/ubuntu-2204/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCanonical发布了Ubuntu22.04.5LTS,作为Ubuntu22.0......
  • P3067 [USACO12OPEN] Balanced Cow Subsets G
    我的天,折半搜索(meetinthemiddle),依稀记得我学过,但是真的不记得。。。。从状态图上起点和终点同时开始进行宽度/深度优先搜索,如果发现相遇了,那么可以认为是获得了可行解。这道题,每一个元素会有3种状态,分别是在第一个集合或者第二个集合亦或者不在集合中。如果直接暴力去搜的......
  • 某景ERP管理系统 UploadInvtSpFile 任意文件上传
    0x01漏洞描述:某景ERP管理系统UploadInvtSpFile存在任意文件上传漏洞,允许攻击者上传恶意文件到服务器,可能导致远程代码执行、网站篡改或其他形式的攻击,严重威胁系统和数据安全。0x02搜索语句:FOFA:body="/api/DBRecord/getDBRecords"0x03漏洞复现:POST/api/cgInvtSp/Upl......
  • Node.js安装与配置(LTS 20.17.0版本)
    目录一、下载Node.js一、下载Node.js1、地址1️⃣下载地址官网:https://nodejs.org/en/download/2️⃣中文镜像地址:下载|Node.js中文网建议:如果没有科学上网,还是镜像好一些,有些时候官网进不去或者下载很慢个人比较喜欢压缩包的方式,没有多余操作,解压即可,弊端就是没有自......
  • nginx 安装服务后,启动报:An attempt was made to access a socket in a way forbidden
    1、nginx1.18.0安装服务成功后,启动服务的时候,一闪直接报错:2、查看Nginx的日志error.log发现启动一次报一条错,并且都是一样的:2024/09/1414:42:18[emerg]6852#6280:bind()to0.0.0.0:80failed(10013:Anattemptwasmadetoaccessasocketinawayforbiddenbyit......
  • LIGGGHTS文件如何在paraview中打开?
            当使用LIGGGHTS进行计算时,会得到.lggghts的文件,而这种文件通常无法在paraview中直接打开。    此时,仅需要找到安装LIGGGHTS的lpp文件中lpp.py文件,便可以将其转化为.vtk格式,方便在paraview中打开。     找到其路径后,利用终端引导至计算案......
  • vue项目之配置本地,测试,生产环境,配置axios.defaults.baseURL,解决跨域问题
    最近在做一个vue项目,想通过不同的命令调用不同环境的api,防止来回手动修改api出错。网上看了好多写的都不全,然后自己突发奇想自己写一篇文章。一、先简单说一下项目搭建1、安装vue脚手架npminstallvue-cli-g2、在硬盘上找一个文件夹放工程用的,在终端中进入该目录cd目录路......
  • 工具分享 | JenkinsExploit-GUI - 一款Jenkins综合漏洞利用工具,一键getshell。
    0x00工具介绍JenkinsExploit-GUI是一款Jenkins综合漏洞利用工具。0x01下载链接JenkinsExploit-GUI下载链接:夸克网盘分享0x02功能介绍CVE-2015-8103/CVE-2016-0788CVE-2016-0792CVE-2017-1000353CVE-2018-1000600CVE-2018-1000861CVE-2018-1999002CVE-20......
  • faststream 自己的asgi 实现
    faststream目前自己包含了一个asgi的实现,可以快速实现api能力,同时也可以与其他web框架集成,以下是一个简单试用参考代码demo.pyfromfaststream.redisimportRedisBroker fromfaststream.asgiimportAsgiFastStream,get,AsgiResponse fromtypingi......