大家好,我叫CUGGZ。TypeScript是微软于2012年推出的一种语言,是JavaScript的超集,具有更强大的可选类型系统。TypeScript和JavaScript一样,有严格模式。今天,我们就来看看如何在TypeScript中开启严格模式,到底有多严格!TypeScript的配置项都写在项目根目录下名为tsconfig.json的配置文件中。可以通过以下方式启用严格模式:{..."compilerOptions":{"strict":true,...},...}TypeScript编译器有90多种不同的配置选项。其中有七个是关于严格模式的:noImplicitAnynoImplicitThisalwaysStrictstrictBindCallApplystrictNullChecksstrictPropertyInitializationstrictFunctionTypes在tsconfig.json中启用严格模式时,相当于启用了这些配置:{..."compilerOptions":{"noImplicitAny":true,"noImplicitThis":true,"alwaysStrict":true,"strictBindCallApply":true,"strictNullChecks":true,"strictFunctionTypes":true,"strictPropertyInitialization":true,...}...}让我们看看这些选项的含义。noImplicitAny此规则不允许变量或函数参数具有隐式任何类型。看下面的例子:constadd10=numbernumber+10;开启严格模式后,函数参数number报错:Theparameter"number"implicitlyhastype"any"。ts(7006)修复这个错误,只需要显式指定参数或变量的类型:constadd10=(number:number)=>number+10;所以noImplicitAny规则可以保证代码更易读。否则,add10函数的调用者需要推断参数是一个数字,那么使用TypeScript有什么意义呢?noImplicitThis该规则不允许this隐式定义上下文。考虑以下示例:classPerson{weight:number;高度:数字;constructor(weight:number,height:number){this.weight=weight;this.height=高度;}getBodyMassIndex(){returnfunction(){returnthis.weight/(this.height*this.height);};}}启用严格模式后,getBodyMassIndex中的this报错:"this"implicitlyhastype"any"becauseithasnotypeannotation。ts(2683)解决这个问题的方法是使用箭头函数,因为箭头函数使用的是父类的执行上下文:classPerson{weight:number;高度:数字;constructor(weight:number,height:number){this.weight=weight;this.height=高度;}getBodyMassIndex(){return(){returnthis.weight/(this.height*this.height);};}}alwaysStrict这条规则指定每个模块总是在严格模式下检查,并在编译后的JavaScript文件中添加“usestrict”来告诉浏览器JavaScript处于严格模式。ES5中引入了ECMAScript严格模式。它只是向编译器提示代码应该在严格模式下执行。使用严格模式可以让代码以更安全、更高效的方式运行。strictBindCallApply此规则确保使用具有正确参数的call()、bind()和apply()函数。看下面的例子:constlogNumber=(x:number)=>{console.log(`number:${x}`)}logNumber.call(undefined,"10");//当启用严格模式时,getBodyMassIndex中的this报错:“string”类型的参数不能赋值给“number”类型的参数。ts(2345)遇到这种错误,只要检查函数调用的参数即可,使用正常的方式调用:logNumber.call(undefined,10);//number:10strictNullChecks这个规则使得null和undefined值不能被赋值对于这两种类型以外的值,其他类型的值不能被赋值。除了any类型之外,还有一个例外就是undefined可以赋值给void类型。此选项可以帮助解决UncaughtTypeError错误。考虑以下示例:interfaceBook{name:string;作者:字符串;}constbooks:Book[]=[{name:'Test1',author:'Max'}];constgetBookByAuthor=(author:string)=>books.find((book)=>book.author=author);constbook=getBookByAuthor("约翰");控制台日志(书名);开启严格模式后,打印book.name会报错:Objectmaybe'undefined'。ts(2532)如果未打开严格模式,即使book.name可能未定义,此代码也会编译。要解决此问题,请向要编译的代码添加空检查:interfaceBook{name:string;作者:字符串;}constbooks:Book[]=[{name:'Test1',author:'Max'}];constgetBookByAuthor=(author:string)=>books.find((book)=>book.author=author);constbook=getBookByAuthor("John");if(book){console.log(book.name);}else{console.log('Booknotfound');}函数是一样的,看下面的例子:interfaceBook{name:string;作者:字符串;}constbooks:Book[]=[{name:'Test1',author:'Max'}];constgetBookByAuthor=(author:string)=>books.find((book)=>book.author=author);}constbook=getBookByAuthor("约翰");constlogBookName=(book:Book)=>{console.log(book.name);}logBookName(book);如果启用严格模式,调用logBookName(book)时会报错:type"Book|undefined"的参数不可赋值给'Book'类型的参数。类型“undefined”不可分配给类型“Book”。ts(2345)在这里提供了两种解决方案:A:设置logBookName函数参数类型为Book|undefinedB:null检查条件调用//AconstlogBookName=(book:Book|undefined)=>{if(book){console.日志(书名);}else{console.log('不是书');}}//Bif(book){logBookName(book);}使用这个规则时,可以强制开发者写出更好的类型描述代码。strictPropertyInitialization这个规则会强制在构造函数中初始化所有的属性值。考虑以下示例:classUser{name:string;年龄:数字;职业:字符串|不明确的;构造函数(名称:字符串){this.name=name;}}上面的代码块中有一个User类,constructor()方法是初始化它的实例属性的地方。JavaScript在实例化类对象时自动调用constructor()方法。Typescript需要初始化已定义的属性,或指定未定义的类型。因此,编译上述代码时,会提示如下错误:Property"age"hasnoinitializerandisnotdefinitelyassignedintheconstructor.ts(2564)对于上面的代码,可以这样改://A:SpecifyundefinedtypeclassUser{name:string;年龄:号码|不明确的;职业:字符串|不明确的;构造函数(名称:字符串){this.name=name;}}//B:初始化定义的属性classUser{name:string;年龄:数字;职业:字符串|不明确的;constructor(name:string,age:number){this.name=name;这个。年龄=年龄;}}strictFunctionTypes此规则更彻底地检查函数参数。默认情况下,Typescript参数是双协变的,这意味着它们既可以是协变的,也可以是逆变的。方差是深入了解子类型关系的一种方式。当参数是协变时,我们可以将特定类型分配给更广泛的类型(例如将子类型分配给超类型)。逆变则相反:可以将更宽的类型分配给特定类型(例如将超类型分配给子类型)。//非严格模式interfaceAnimal{name:string;}interfaceDogextendsAnimal{breeds:Array
