我们在开发TypeScript代码时,很可能会遇到any关键字。我们看到的大多数用法表明我们正在处理TypeScript中的原始类型。在文档中我们可能会发现:(...)不使用TypeScript或第3方库来编写代码的值。在这些情况下,我们可能希望选择退出类型检查。为此,我们将这些值标记为任何类型。any所以any不是通配符也不是基本类型,它明确用于与3rd方库交互。那为什么它经常出现在你身上呢?它对我们的系统有害吗?我们应该逃避它还是拥抱它?any类型是使用现有JavaScript的一种强大方式,允许您在编译期间逐渐选择加入和退出类型检查。TypeScript文档清楚地表明,当我们使用any类型时,我们是在告诉编译器:当超过500名语言贡献者提供帮助时,我们说不,谢谢。这听起来像是一种选择退出类型检查器,使用它不能轻易放弃对类型系统的所有安全性和信心。我们应该使用它来与无类型的第三方(或第一方)Javascript代码交互,或者当我们只知道部分类型时。但是等等,我还有很多其他原因(1)TypeScript不能转换为Javascript吗?Javascript不是动态的吗?那我为什么要考虑我的类型呢?是的!但是我们用TypeScript编写代码,它是一种静态类型语言。有人可能会争辩说,静态类型语言产生的错误并不比动态类型语言少。尽管如此,在像任何一种静态类型的语言中,这是两者中最糟糕的。(2)有些参数很难正确输入,但任何一个都比较容易。如果我们不正确地输入,我们将写入错误,比我们在动态语言中的错误更多,因为我们强制使用TypeScript,一种静态类型的语言,来检查不正确的类型。(3)我真的不知道论点是什么没关系!我们可以使用unknown;它允许我们分配给任何类型。但在确定特定类型之前,我们不会允许使用这些值。typeParsedType={id:number}constparseApiResponse(response:Record):ParsedType=>{constconvertedResponse=(responseasParsedType)//不做类型转换我们会//getatypeerrorhereif(convertedResponse.id>=0){returnconvertedResponse{throwErse}("Invalidresponse"}}(4)添加类型时我必须写很多代码,任何一个都不太可能工作,如果我们编写没有类型的代码那么我们可能需要添加防御代码以确保参数和变量具有正确以允许程序按预期执行。any甚至不防止null或undefined检查我们的逻辑。//version1with`any`constfullName=(user:any)=>{if(user?.firstName&&user?.lastName){return`${user.lastName},${user.firstName}`}returnuser?.firstName||""}//version1without`any`interfaceUser{firstName:stringlastName?:string}constfullName=({firstName,lastName}:User)=>{if(lastName===undefined){returnfirstName}return`${lastName},${firstName}`;}(5)类型增加了很多复杂性,有时any更简单ingany可以让我们更容易开发,而无需考虑数据如何流入逻辑。但它将这种负担转移到了我们代码的未来读者身上。他们将不得不在没有上下文且没有编译器帮助的情况下解释发生了什么。(6)有了文档,我可以提供所有上下文当添加类型时,我们从编译器那里得到帮助,我们得到的文档不会随着时间的推移而衰减,因为如果它过时了,我们的代码将无法编译。constintersection=(a:any,b:any):any=>{...}constintersection=(a:Set,b:Set):Set=>{...}他们都是等价的,但读者会比从第一个开始更了解后面的函数在做什么。(7)我以防御性方式编写了代码,并进行了必要的运行时检查以确保没有错误。现在可能没有bug,但是除非你有很好的测试覆盖率,否则后来来修改代码的人不会相信他们不是在错误地重构;就好像编译器不会帮助你,因为我们说过它不会。如果我们显式设置类型并更改系统中使用的API,编译器将提供其指导。(8)如果我以后改变主意怎么办?我可能会重构这个几个小时。我们总是可以修改和适应新的类型定义,TypeScript为此提供了一组实用函数。我们可以使用Pick习惯从先前定义的类型中选择所需的属性。省略除了少数之外的一切。部分使所有属性成为可选的,或者做一个完整的180并使它们全部成为必需的。typeUser={id:number;firstName:string;lastName:string;age:number;}typeUserParams=Pick&Partial>constupdateUser=({id,...newUserParams}:UserParams)=>{{...}}(9)太好了,从TypeScript中删除任何,现在打开PR让我们深吸一口气,任何它在正确的情况下都非常强大和有用。与使用它的库交互;确保在将数据移动到系统之前尽快将其转换为正确的类型。解决TypeScript类型错误;如果我们发现自己无法输入某些内容,则可能需要任何。但只有在尝试了所有其他方法后才建议这样做。如果使用它,我们应该将其重铸为可预测的类型。如果我们的函数真的可以处理任何类型(例如调试或日志记录函数),那么这种情况很少见且是偶然的。在这些情况下,我们需要100%确定没有任何类型会导致函数失败。我们应该检查函数体并根据输入确定最基本的形状和约束。例如,如果我们正在打印一些东西,我们至少应该验证它是否响应toString。让我们回顾一下为什么我们不能再使用了?它使编译器过时,我们告诉编译器:我不需要你的帮助我们放弃了在编写代码时记录代码的机会我们的第一道防线被攻破在动态语言中,我们假设事物可以有类型any,我们采用的模式遵循这个假设。如果我们开始将静态类型语言用作动态语言,那么我们就是在与范式作斗争,并且在我们继续对代码库进行更改时,没有任何东西可以指导/帮助我们。自由越大,责任越大(编译器)。不要成为编译器,我们的目的是使用编译器。