专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

TypeScript5。0Beta来了

  今天,我们很高兴地宣布TypeScript5。0的测试版发布!
  此版本带来了许多新功能,同时旨在使TypeScript更小、更简单、更快。我们已经实现了新的装饰器标准、更好地支持Node和捆绑器中的ESM项目的功能、库作者控制泛型推理的新方法、扩展了我们的JSDoc功能、简化了配置,并进行了许多其他改进。
  虽然5。0版本包括正确性更改和对较少使用的标志的弃用,但我们相信大多数用户将拥有与以前版本类似的升级体验。
  要开始使用测试版,您可以通过NuGet获取它,或通过以下命令使用npm:npminstalltypescriptbeta装饰器
  装饰器是即将推出的ECMAScript功能,它允许我们以可重用的方式自定义类及其成员。
  让我们考虑以下代码:classPerson{name:string;constructor(name:string){this。namename;}greet(){console。log(Hello,mynameis{this。name}。);}}constpnewPerson(Ray);p。greet();
  greet在这里非常简单,但让我们想象它是更复杂的东西也许它执行一些异步逻辑,它是递归的,它有副作用等等。不管你想象的是哪种,假设你调用console。log输出一些以帮助调试问候语。classPerson{name:string;constructor(name:string){this。namename;}greet(){console。log(LOG:Enteringmethod。);console。log(Hello,mynameis{this。name}。);console。log(LOG:Exitingmethod。)}}
  这种模式相当常见。如果有一种方法可以让我们对每个方法都这样做,那就太好了!
  这就是装饰器的作用。我们可以编写一个名为loggedMethod的函数,如下所示:functionloggedMethod(originalMethod:any,context:any){functionreplacementMethod(this:any,。。。args:any〔〕){console。log(LOG:Enteringmethod。)constresultoriginalMethod。call(this,。。。args);console。log(LOG:Exitingmethod。)returnresult;}returnreplacementMethod;}
  这些any是怎么回事?
  耐心点我们现在让事情变得简单,这样我们就可以专注于这个函数在做什么。注意,loggedMethod接受原始方法(originalMethod)并返回一个函数记录一条输入(Entering)的消息将this及其所有参数传递给原始方法记录退出(Exiting)消息返回原始方法返回的值
  现在我们可以使用loggedMethod来装饰greet:classPerson{name:string;constructor(name:string){this。namename;}loggedMethodgreet(){console。log(Hello,mynameis{this。name}。);}}constpnewPerson(Ray);p。greet();Output:LOG:Enteringmethod。Hello,mynameisRay。LOG:Exitingmethod。
  我们只是在greet上面使用了loggedMethod作为装饰器注意,我们把它写成了loggedMethod。当我们这样做时,它会被target方法和一个context对象调用。因为loggedMethod返回了一个新函数,所以这个函数替换了greet的原始定义。
  loggedMethod定义了第二个参数。它被称为上下文对象,它有一些关于修饰方法是如何声明的有用信息比如它是private成员或者是静态的,或者方法的名称是什么。让我们重写loggedMethod来利用这一点,并打印出被装饰的方法的名称。functionloggedMethod(originalMethod:any,context:ClassMethodDecoratorContext){constmethodNameString(context。name);functionreplacementMethod(this:any,。。。args:any〔〕){console。log(LOG:Enteringmethod{methodName}。)constresultoriginalMethod。call(this,。。。args);console。log(LOG:Exitingmethod{methodName}。)returnresult;}returnreplacementMethod;}
  我们现在使用context参数它是loggedMethod中第一个类型比any和any〔〕更严格的参数。TypeScript提供了一个名为ClassMethodDecoratorContext的类型,它为方法装饰器接受的上下文对象建模。
  除了元数据,方法的上下文对象还有一个有用的函数addInitializer。这是一种挂接到构造函数开头的方式(如果使用静态方法,则挂接到类本身的初始化)。
  举个例子在JavaScript中,经常会写如下的模式:classPerson{name:string;constructor(name:string){this。namename;this。greetthis。greet。bind(this);}greet(){console。log(Hello,mynameis{this。name}。);}}
  或者,可以将greet声明为一个初始化为箭头函数。classPerson{name:string;constructor(name:string){this。namename;}greet(){console。log(Hello,mynameis{this。name}。);};}
  编写这段代码是为了确保当greet作为独立函数调用或作为回调函数传递时,不会重新绑定。constgreetnewPerson(Ray)。greet;我们不想这里出错greet();
  我们可以编写一个装饰器,使用addInitializer在构造函数中为我们调用bind。functionbound(originalMethod:any,context:ClassMethodDecoratorContext){constmethodNamecontext。name;if(context。private){thrownewError(boundcannotdecorateprivatepropertieslike{methodNameasstring}。);}context。addInitializer(function(){this〔methodName〕this〔methodName〕。bind(this);});}
  当Bound装饰一个方法时它不会返回任何东西,它会保留原来的方法。相反,它会在其他字段初始化之前添加逻辑。classPerson{name:string;constructor(name:string){this。namename;}boundloggedMethodgreet(){console。log(Hello,mynameis{this。name}。);}}constpnewPerson(Ray);constgreetp。greet;Works!greet();
  注意,我们用了两个装饰器bound和loggedMethod。这些装饰是以相反的顺序运行的。也就是说,loggedMethod修饰了原始方法greet,bound修饰了loggedMethod的结果。在这个例子中,这没有关系但如果你的装饰器有副作用或期望某种顺序,则需要关注他们的顺序。
  同样值得注意的是如果你更喜欢代码风格化,你可以将这些装饰器放在同一行。boundloggedMethodgreet(){console。log(Hello,mynameis{this。name}。);}
  可能不太明显的是,我们甚至可以创建返回装饰器函数的函数。这使得我们可以对最终的装饰器进行一些自定义。如果我们愿意,我们可以让loggedMethod返回一个装饰器,并自定义它记录消息的方式。functionloggedMethod(headMessageLOG:){returnfunctionactualDecorator(originalMethod:any,context:ClassMethodDecoratorContext){constmethodNameString(context。name);functionreplacementMethod(this:any,。。。args:any〔〕){console。log({headMessage}Enteringmethod{methodName}。)constresultoriginalMethod。call(this,。。。args);console。log({headMessage}Exitingmethod{methodName}。)returnresult;}returnreplacementMethod;}}
  如果我们这样做,我们必须在使用loggedMethod作为装饰器之前调用它。然后,我们可以传入任何字符串作为输出到控制台的消息的前缀。classPerson{name:string;constructor(name:string){this。namename;}loggedMethod()greet(){console。log(Hello,mynameis{this。name}。);}}constpnewPerson(Ray);p。greet();Output:Enteringmethodgreet。Hello,mynameisRay。Exitingmethodgreet。
  装饰器可不仅仅用于方法!它们可以用于属性字段、getter、setter和自动访问器。甚至类本身也可以装饰成子类化和注册。
  有关所涉及更改的更多信息,您可以查看原始的pullrequest。与实验性遗留装饰器的差异
  如果你已经使用TypeScript一段时间了,你可能会意识到它多年来一直支持实验性装饰器。虽然这些实验性装饰器非常有用,但它们模拟了装饰器提案的一个更旧的版本,并且总是需要一个称为experimentalDecorators的可选编译器标志。任何在TypeScript中不使用此标志的尝试都会提示错误。
  实验性装饰器将在可预见的未来继续存在;但是,如果没有这个标志,装饰器将成为所有新代码的有效语法。在experimentalDecorators之外,它们将被类型检查并以不同的方式发出。类型检查规则和emit有很大的不同,虽然可以编写装饰器来同时支持新旧装饰器行为,但任何现有的装饰器函数都不太可能这样做。
  这个新的装饰器提案与emitDecoratorMetadata不兼容,而且它不允许装饰参数。未来的ECMAScript提案可能有助于弥合这一差距。
  最后说一句:目前,装饰器的提案要求类装饰器在export关键字之后(如果存在的话)。exportregisterclassFoo{。。。}exportComponent({。。。})classBar{。。。}
  TypeScript会在JavaScript文件中强制执行此限制,但TypeScript文件不会这样做。这部分是由现有用户驱动的我们希望在我们原始的实验性装饰器和标准化装饰器之间提供一个稍微简单的迁移路径。此外,我们从许多用户那里听到了对原始样式的偏好,我们希望在未来的标准讨论中真诚地讨论这个问题。编写类型良好的装饰器
  上面的loggedMethod和bound装饰器示例很简单,并省略了大量关于类型的细节。
  输入装饰器可能相当复杂。例如,上面的loggedMethod类型良好的版本可能看起来像这样:functionloggedMethodThis,Argsextendsany〔〕,Return(target:(this:This,。。。args:Args)Return,context:ClassMethodDecoratorContextThis,(this:This,。。。args:Args)Return){constmethodNameString(context。name);functionreplacementMethod(this:This,。。。args:Args):Return{console。log(LOG:Enteringmethod{methodName}。)constresulttarget。call(this,。。。args);console。log(LOG:Exitingmethod{methodName}。)returnresult;}returnreplacementMethod;}
  我们必须使用this、Args和return类型参数分别建模this、参数和原始方法的返回类型。
  具体定义装饰器函数的复杂程度取决于你想要什么。请记住,你的装饰器的使用次数将超过它们的编写次数,所以类型良好的版本通常是更好的但显然需要与可读性权衡,所以请尽量保持简单。
  constType参数
  在推断对象的类型时,TypeScript通常会选择一种通用的类型。例如,在这个例子中,names的推断类型是string〔〕:typeHasNames{readonlynames:string〔〕};functiongetNamesExactlyTextendsHasNames(arg:T):T〔names〕{returnarg。names;}Inferredtype:string〔〕constnamesgetNamesExactly({names:〔Alice,Bob,Eve〕});
  通常这样做的目的是实现突变。
  然而,根据getnames确切的作用以及它的使用方式,通常情况下需要更具体的类型。
  到目前为止,API作者通常不得不建议在某些地方添加const,以实现所需的推断:希望类型是:readonly〔Alice,Bob,Eve〕但类型变成:string〔〕constnames1getNamesExactly({names:〔Alice,Bob,Eve〕});正确获得想要的类型:readonly〔Alice,Bob,Eve〕constnames2getNamesExactly({names:〔Alice,Bob,Eve〕}asconst);
  这可能很麻烦,也很容易忘记。在TypeScript5。0中,你现在可以在类型参数声明中添加const修饰符,以使const类推断成为默认值:typeHasNames{names:readonlystring〔〕};functiongetNamesExactlyconstTextendsHasNames(arg:T):T〔names〕{returnarg。names;}Inferredtype:readonly〔Alice,Bob,Eve〕Note:DidntneedtowriteasconsthereconstnamesgetNamesExactly({names:〔Alice,Bob,Eve〕});
  注意,const修饰符并不排斥可变值,也不需要不可变约束。使用可变类型约束可能会得到令人惊讶的结果。例如:declarefunctionfnBadconstTextendsstring〔〕(args:T):void;T仍旧是string〔〕因为readonly〔a,b,c〕没有赋值为string〔〕fnBad(〔a,b,c〕);
  这里,T的推断候选值是readonly〔a,b,c〕,而readonly数组不能用于需要可变数组的地方。在这种情况下,推理回退到约束,数组被视为string〔〕,调用仍然成功进行。
  更好的定义应该使用readonlystring〔〕:declarefunctionfnGoodconstTextendsreadonlystring〔〕(args:T):void;Tisreadonly〔a,b,c〕fnGood(〔a,b,c〕);
  同样,要记住,const修饰符只影响在调用中编写的对象、数组和基本类型表达式的推断,所以不会(或不能)用const修饰的参数不会看到任何行为的变化:declarefunctionfnGoodconstTextendsreadonlystring〔〕(args:T):void;constarr〔a,b,c〕;Tisstillstring〔〕theconstmodifierhasnoeffectherefnGood(arr);
  支持多个配置文件
  当管理多个项目时,从基础配置文件tsconfig。Json继承会很有帮助。使用extends字段,用于从compilerOptions中复制字段。packagesfrontendsrctsconfig。json{compilerOptions:{extends:。。。。。。tsconfig。base。json,outDir:。。lib,。。。}}
  然而,在某些情况下,您可能希望从多个配置文件扩展。例如,想象一下使用npm中的TypeScript基础配置文件。如果你希望所有项目都使用npm上tsconfigstrictest包中的选项,那么有一个简单的解决方案:从tsconfigstrictest扩展tsconfig。base。json:tsconfig。base。json{compilerOptions:{extends:tsconfigstrictesttsconfig。json,。。。}}
  这在一定程度上是可行的。如果有项目不想使用tsconfigstrictest,就必须手动禁用该选项,或者创建一个不扩展tsconfigstrictest的单独版本的tsconfig。base。json。
  为了在这里提供更多的灵活性,Typescript5。0现在允许extends字段接收多个条目。例如,在这个配置文件中:{compilerOptions:{extends:〔a,b,c〕}}
  这样写有点像直接扩展c,其中c扩展b,b扩展a。如果任何字段冲突,则后一项获胜。
  因此,在下面的例子中,strictNullChecks和noImplicitAny都在最终的tsconfig。json文件中启用了。tsconfig1。json{compilerOptions:{strictNullChecks:true}}tsconfig2。json{compilerOptions:{noImplicitAny:true}}tsconfig。json{compilerOptions:{extends:〔。tsconfig1。json,。tsconfig2。json〕},files:〔。index。ts〕}
  作为另一个例子,我们可以用下面的方式重写原来的。packagesfrontendsrctsconfig。json{compilerOptions:{extends:〔tsconfigstrictesttsconfig。json,。。。。。。tsconfig。base。json〕,outDir:。。lib,。。。}}
  有关更多细节,请阅读原始pullrequest的更多信息。所有枚举都是Union枚举
  当TypeScript最初引入枚举时,它们只不过是一组具有相同类型的数值常量。enumE{Foo10,Bar20,}
  E。Foo和E。Bar唯一的特别之处在于它们可以赋值给任何期望类型为E的东西。除此之外,它们基本上都是数字。functiontakeValue(e:E){}takeValue(E。Foo);workstakeValue(123);error!
  直到TypeScript2。0引入了枚举字面量类型,枚举才变得更加特殊。Enum字面量类型为每个枚举成员指定了自己的类型,并将枚举本身转换为每个成员类型的并集。它们还允许我们只引用枚举类型的一个子集,并缩小这些类型的范围。enumColor{Red,Orange,Yellow,Green,Blue,Indigo,Violet}每个枚举成员都有自己的类型,可以引用!typePrimaryColorColor。RedColor。GreenColor。Blue;functionisPrimaryColor(c:Color):CisPrimaryColor{缩小字面量类型可以捕获bugTypeScript在这里会报错,因为我们最终会比较Color。Color。从Red到Color。Green。我们本想使用,但不小心写了returncColor。RedcColor。GreencColor。Blue;}
  给每个枚举成员指定自己的类型有一个问题,即这些类型在某种程度上与成员的实际值相关联。在某些情况下,这个值是不可能计算出来的例如,枚举成员可以通过函数调用进行初始化。enumE{BlahMath。random()}
  每当TypeScript遇到这些问题时,它都会悄无声息地退出并使用旧的枚举策略。这意味着要放弃并集和字面量类型的所有优点。
  TypeScript5。0通过为每个计算成员创建唯一的类型,设法将所有枚举转换为联合枚举。这意味着现在可以缩小所有枚举的范围,并将其成员作为类型引用。
  有关此更改的更多详细信息,请参阅GitHub上的详细说明。moduleResolution打包
  TypeScript4。7为其module和modulerresolution设置引入了node16和nodenext选项。这些选项的目的是为了更好地在Node。js中为ECMAScript模块建立精确的查找规则模型。然而,这种模式有许多其他工具没有真正实施的限制。
  例如,在Node。js的ECMAScript模块中,任何相对导入都需要包含文件扩展名。entry。mjsimportasutilsfrom。utils;wrong需要包含文件扩展名importasutilsfrom。utils。mjs;works
  在Node。js和浏览器中这样做是有原因的它使文件查找更快,并且对于简单的文件服务器工作得更好。但对于许多使用打包工具的开发人员来说,node16nodenext的设置很麻烦,因为打包工具没有这些限制。在某种程度上,node解析模式更适合任何使用打包工具的人。
  但在某些方面,最初的node解析模式已经过时了。大多数现代打包工具融合了Node。js中的ECMAScript模块和CommonJS查找规则。例如,无扩展导入就像在CommonJS中一样正常工作,但当查看包的导出条件时,他们会更喜欢ECMAScript文件中的导入条件。
  为了建模打包的工作方式,TypeScript现在引入了一个新的策略:modulerresolution打包。{compilerOptions:{target:esnext,moduleResolution:bundler}}
  如果你正在使用现代的打包工具,比如Vite、esbuild、swc、Webpack、Parcel,以及其他实现了混合查找策略的工具,那么新的打包工具选项应该很适合你。
  要了解有关modulerresolution打包工具的更多信息,请查看实现的拉取请求。解析自定义标志
  JavaScript工具现在可以对混合解析规则建模,就像我们上面描述的打包模式一样。由于工具的支持可能略有不同,TypeScript5。0提供了启用或禁用一些功能的方法,这些功能可能与您的配置一起使用,也可能无法使用。allowImportingTsExtensions
  allowImportingTsExtensions允许TypeScript文件使用特定于TypeScript的扩展名(如。ts、。mts或。tsx)相互导入。
  仅当启用noEmit或emitDeclarationOnly时,才允许使用此标志,因为这些导入路径在运行时无法在JavaScript输出文件中解析。这里的期望是你的解析器(例如打包、运行时或其他工具)将使这些在。ts文件之间的导入正常工作。resolvePackageJsonExports
  resolvePackageJsonExports强制TypeScript查询package的exports字段。如果它从nodemodules中的包中读取数据,则会读取Json文件。
  在moduleResolution的node16、nodenext和bundler选项中,这个选项默认为true。resolvePackageJsonImports
  resolvePackageJsonImports强制TypeScript查询package的imports字段。当查找以开头的文件时,该文件的祖先目录包含package。json文件。
  在moduleResolution的node16、nodenext和bundler选项中,这个选项默认为true。allowArbitraryExtensions
  在TypeScript5。0中,当导入路径以一个不是已知的JavaScript或TypeScript文件扩展名的扩展名结束时,编译器将查找该路径形式为{filebasename}。d。{extension}。ts的声明文件。例如,如果你在打包项目中使用CSSloader,你可能想为这些样式表编写(或生成)声明文件:app。css。cookiebanner{display:none;}app。d。css。tsdeclareconstcss:{cookieBanner:string;};exportdefaultcss;App。tsximportstylesfrom。app。css;styles。cookieBanner;string
  默认情况下,这个导入将引发一个错误,让你知道TypeScript不理解这个文件类型,你的运行时可能不支持导入它。但是,如果您已经配置了运行时或打包器来处理它,则可以使用新的allowArbitraryExtensions编译器选项来抑制错误。
  请注意,在历史上,通常通过添加一个名为app。css。d。ts的声明文件而不是app。d。css。ts来实现类似的效果然而,这只是通过Node对CommonJS的require解析规则实现的。严格来说,前者是一个名为app。css。js的JavaScript文件的声明文件。因为相对文件导入需要包含Node对ESM支持的扩展,所以在我们的例子中,TypeScript会在moduleResolutionnode16或nodenext下的ESM文件中出错。
  有关更多信息,请阅读此功能的建议及其相应的pullrequest。customConditions
  customConditions接受额外的条件列表,当TypeScript从package。json的〔exports〕或(https:nodejs。orgapipackages。htmlexports)或imports字段解析时,这些条件应该成功。这些条件将添加到解析器默认使用的任何现有条件中。
  例如,当在tsconfig。conf中设置此字段时。Json格式如下:{compilerOptions:{target:es2022,moduleResolution:bundler,customConditions:〔mycondition〕}}
  在包中引用exports或imports字段时。TypeScript将考虑mycondition条件。
  因此,当使用以下package。json从一个包中导入时{。。。exports:{。:{mycondition:。foo。mjs,node:。bar。mjs,import:。baz。mjs,require:。biz。mjs}}}
  TypeScript将尝试查找与foo。mjs对应的文件。
  这个字段只有在node16、nodenext和bundler选项下modulerresolution才有效verbatimModuleSyntax
  默认情况下,TypeScript会执行导入省略(importelision)操作。基本上,如果你写import{Car}from。car;exportfunctiondrive(car:Car){。。。}
  TypeScript检测到你只使用了类型导入,并完全删除导入。输出的JavaScript代码可能类似于下面这样:exportfunctiondrive(car){。。。}
  大多数情况下,这是很好的,因为如果Car不是从。Car导出的值,我们会得到一个运行时错误。
  但对于某些边界情况,它确实增加了一层复杂性。例如,没有import。car这样的语句;完全放弃导入。这实际上对有没有副作用的模块有影响。
  TypeScript的JavaScriptemit策略也有另外几层复杂性省略导入并不总是由如何使用导入驱动的它通常还会咨询如何声明值。因此,下面的代码是否像下面这样并不总是很清楚export{Car}from。car;
  应保存或丢弃。如果Car使用类之类的东西声明,那么它可以保留在生成的JavaScript文件中。但是,如果Car仅被声明为类型别名或接口,那么JavaScript文件根本不应该导出Car。
  虽然TypeScript可能能够根据来自跨文件的信息做出这些发送决策,但不是每个编译器都可以。
  导入和导出的类型修饰符在这些情况下有一点帮助。我们可以明确指定import或export仅用于类型分析,并且可以在JavaScript文件中使用类型修饰符完全删除。这条语句可以在JS输出中完全删除importtypeascarfrom。car;在JS输出中可以去掉命名的importexportCarimport{typeCar}from。car;export{typeCar}from。car;
  类型修饰符本身并不是很有用默认情况下,模块省略仍然会删除导入,并且没有任何东西迫使你区分类型和普通的导入和导出。因此,TypeScript有标志importsNotUsedAsValues以确保您使用类型修饰符,preserveValueImports以防止某些模块省略行为,以及isolatedModules以确保您的TypeScript代码在不同的编译器上工作。不幸的是,理解这3个标志的细节是困难的,并且仍然存在一些具有意外行为的边缘情况。
  TypeScript5。0引入了一个名为verbatimModuleSyntax的新选项来简化这种情况。规则要简单得多没有类型修饰符的任何导入或导出都将保留。任何使用类型修饰符的元素都被完全删除。完全抹去importtype{A}froma;重写import{b}frombcd;import{b,typec,typed}frombcd;重写import{}fromxyz;import{typexyz}fromxyz;
  有了这个新选项,所见即所得。
  不过,当涉及到模块互操作时,这确实有一些含义。在这个标志下,当你的设置或文件扩展名意味着需要使用不同的模块系统时,ECMAScript的import和export函数不会被重写。相反,你会得到一个错误。如果你需要发出使用require和module的代码。导出时,你必须使用ES2015之前的TypeScript模块语法:
  虽然这是一个限制,但它确实有助于使一些问题更加明显。例如,在package。json中忘记设置type字段是很常见。因此,开发人员会在不知不觉中开始编写CommonJS模块,而不是ES模块,给出令人惊讶的查找规则和JavaScript输出。这个新标志确保你有意使用不同的文件类型,因为它们的语法是不同的。
  因为verbatimModuleSyntax比importsNotUsedAsValues和preserveValueImports提供了一个更一致的事实,所以这两个现有的标志被弃用了。支持foreexport类型
  当TypeScript3。8引入纯类型导入时,新语法不允许从module导出或从module重新导出ns时导出。TypeScript5。0增加了对这两种形式的支持:modelsvehicles。tsexportclassSpaceship{。。。}modelsindex。tsexporttypeasvehiclesfrom。spaceship;main。tsimport{vehicles}from。models;functiontakeASpaceship(s:vehicles。Spaceship){okvehicles只在type位置使用}functionmakeASpaceship(){returnnewvehicles。Spaceship();vehicles不能用作值,因为它是使用exporttype导出的。}
  JSDoc中的satisfiesSupport
  TypeScript4。9引入了satisfaction操作符。它确保表达式的类型是兼容的,而不会影响类型本身。例如,让我们看看下面的代码:interfaceCompilerOptions{strict?:boolean;outDir?:string;。。。extends?:stringstring〔〕;}declarefunctionresolveConfig(configPath:string):CompilerOptions;letmyCompilerOptions{strict:true,outDir:。。lib,。。。extends:〔tsconfigstrictesttsconfig。json,。。。。。。tsconfig。base。json〕,}satisfiesCompilerOptions;
  在这里,TypeScript知道myCompilerOptions。extends是用数组声明的因为while满足验证了对象的类型,它不会直接将其更改为CompilerOptions并丢失信息。如果我们想映射到extends,没问题。letinheritedConfigsmyCompilerOptions。extends。map(resolveConfig);
  这对TypeScript用户很有帮助,但是很多人使用TypeScript使用JSDoc注释对JavaScript代码进行类型检查。这就是为什么TypeScript5。0支持一个名为satisfy的新JSDoc标签,它做的事情完全相同。
  satisfy可以捕获类型不匹配:tschecktypedefCompilerOptionsprop{boolean}〔strict〕prop{string}〔outDir〕prop{stringstring〔〕}〔extends〕satisfies{CompilerOptions}letmyCompilerOptions{outdir:。。lib,oops!wemeantoutDir};
  但它将保留表达式的原始类型,允许我们在后面的代码中更精确地使用值。tschecktypedefCompilerOptionsprop{boolean}〔strict〕prop{string}〔outDir〕prop{stringstring〔〕}〔extends〕satisfies{CompilerOptions}letmyCompilerOptions{strict:true,outDir:。。lib,extends:〔tsconfigstrictesttsconfig。json,。。。。。。tsconfig。base。json〕,};letinheritedConfigsmyCompilerOptions。extends。map(resolveConfig);
  satisfies也可以在任何括号表达式中使用。我们可以这样写myCompilerOptions:letmyCompilerOptionssatisfies{CompilerOptions}({strict:true,outDir:。。lib,extends:〔tsconfigstrictesttsconfig。json,。。。。。。tsconfig。base。json〕,});
  为什么?好吧,当你深入到其他代码中时,比如函数调用,它通常更有意义。compileCode(satisfies{CompilerOptions}({。。。}));
  此功能由OleksandrTarasiuk提供!JSDoc中的overloadSupport
  在TypeScript中,你可以为函数指定重载。重载为我们提供了一种方式,可以使用不同的参数调用函数,并可能返回不同的结果。它们可以限制调用者实际可以如何使用我们的函数,并细化他们将返回的结果。Ouroverloads:functionprintValue(str:string):void;functionprintValue(num:number,maxFractionDigits?:number):void;Ourimplementation:functionprintValue(value:stringnumber,maximumFractionDigits?:number){if(typeofvaluenumber){constformatterIntl。NumberFormat(enUS,{maximumFractionDigits,});valueformatter。format(value);}console。log(value);}
  这里我们说过,printValue的第一个参数要么是字符串,要么是数字。如果它接收一个数字,那么它可以接收第二个实参来确定我们可以打印多少个小数。
  TypeScript5。0现在允许JSDoc使用新的overload标签来声明重载。每个带有overload标签的JSDoc注释都被视为下面函数声明的不同重载。tscheckoverloadparam{string}valuereturn{void}overloadparam{number}valueparam{number}〔maximumFractionDigits〕return{void}param{stringnumber}valueparam{number}〔maximumFractionDigits〕functionprintValue(value,maximumFractionDigits){if(typeofvaluenumber){constformatterIntl。NumberFormat(enUS,{maximumFractionDigits,});valueformatter。format(value);}console。log(value);}
  现在,无论我们是使用TypeScript还是JavaScript文件编写,TypeScript都可以让我们知道我们是否错误地调用了函数。allallowedprintValue(hello!);printValue(123。45);printValue(123。45,2);printValue(hello!,123);error!
  在build下传递特定的标志
  TypeScript现在允许在build模式下传递以下标志declarationemitDeclarationOnlydeclarationMapsoureMapinlineSourceMap
  这使得您可以更容易地自定义构建的某些部分,其中可能有不同的开发和生产构建。
  例如,开发版本的库可能不需要生成声明文件,但生产版本需要。项目可以配置声明发射为默认关闭,并简单地进行构建tscbuildp。myprojectdir
  完成内部循环后,生产构建只需传递declaration标志即可。tscbuildp。myprojectdirdeclaration
  ExhaustiveswitchcaseCompletions
  当编写switch语句时,TypeScript现在会检测被检查的值何时具有文字类型。如果是这样,它将为每个case提供一个完整的框架。
  速度、内存和包大小的优化
  TypeScript5。0在我们的代码结构、数据结构和算法实现方面包含了许多强大的更改。这些都意味着你的整个体验应该更快不仅仅是运行TypeScript,甚至是安装它。
  相对于TypeScript4。9,我们在速度和大小方面取得了一些有趣的胜利。
  场景
  相对于TS4。9时间或者大小
  Materialui构建时间
  90
  Playwright构建时间
  89
  tsc启动时间
  89
  tsc构建时间
  86
  Outlook构建时间
  83
  VSCode构建时间
  81
  typescript打包大小
  58
  换句话说,我们发现TypeScript5。0Beta版构建VSCode所花费的时间仅为TypeScript4。9的81。
  如何?有一些值得注意的改进,我们希望在未来提供更多的细节。但我们不会让你等待那篇博客文章。
  首先,我们最近将TypeScript从命名空间迁移到模块,允许我们利用现代构建工具来执行作用域提升等优化。使用这个工具,重新审视我们的打包策略,并移除一些废弃的代码,已经从TypeScript4。9的63。8MB包大小中削减了约26。5MB。通过直接调用函数,它也显著地提高了速度。
  TypeScript还为编译器中的内部对象类型增加了更多的一致性,同时也精简了某些对象类型。这减少了多态和大态的使用站点,同时抵消了一些作为权衡而来的内存占用。
  我们还在将信息序列化为字符串时执行了一些缓存。类型显示,可能作为错误报告、声明发出、代码完成等的一部分发生,最终可能会非常昂贵。TypeScript现在缓存了一些常用的机制,以便在这些操作中重用。
  总的来说,我们期望大多数代码库从TypeScript5。0开始速度都将得到提升,并始终能够重现10到20的优势。当然,这取决于硬件和代码库的特性,但我们鼓励您今天就在代码库中尝试一下!
  运行时的要求
  TypeScript现在以ECMAScript2018为目标。对于Node用户来说,这意味着最低版本要求至少是Node。js10及更高版本。lib。d。ts变更
  DOM类型生成方式的改变可能会对现有代码产生影响。值得注意的是,某些属性已经从数值类型转换为数值字面量类型,处理cut、copy和paste事件的属性和方法也在不同接口之间进行了移动。API重大变化
  在TypeScript5。0中,我们转向了模块,删除了一些不必要的接口,并对正确性进行了一些改进。有关更改的更多详细信息,请参阅我们的API重大更改页面。关系运算符中禁止的隐式强制操作
  如果你编写的代码可能导致隐式的字符串到数字转换,TypeScript中的某些操作将会警告你:functionfunc(ns:numberstring){returnns4;Error,可能的隐式转换}
  在5。0中,这也适用于关系操作符、、和:functionfunc(ns:numberstring){returnns4;错误}
  如果需要,可以使用显式强制操作数为数字:functionfunc(ns:numberstring){returnns4;OK}
  这种正确性的改进由Mateusz提供Burzyski。Enum改革
  自TypeScript第一次发布以来,枚举一直存在一些奇怪的问题。在5。0中,我们清理了其中的一些问题,同时减少了理解可以声明的各种枚举所需的概念数量。
  你可能会看到两个主要的新错误。第一,将域外字面量赋值给enum类型现在会出错,正如我们所料:enumSomeEvenDigit{Zero0,Two2,Four4}错误letm:SomeEvenDigit1;
  另一个问题是,声明某种类型的间接字符串数字混合枚举形式会错误地创建一个全数字枚举:enumLetters{Aa}enumNumbers{one1,twoLetters。A}Nowcorrectlyanerrorconstt:numberNumbers。two;
  在experimentalDecorators下为构造函数中的参数装饰器进行更准确的类型检查
  TypeScript5。0使得experimentalDecorators下的装饰器的类型检查更加准确。在对构造函数参数使用装饰器时,这一点变得很明显。exportdeclareconstinject:(entity:any)(target:object,key:stringsymbol,index?:number)void;exportclassFoo{}exportclassC{constructor(inject(Foo)privatex:any){}}
  这个调用将失败,因为key需要一个stringsymbol,但构造函数参数接收到的键是undefined。正确的修复方法是改变inject中的key类型。如果你使用的库无法升级,一个合理的解决方案是将inject包装在一个更类型安全的装饰器函数中,并对键使用类型断言。
  弃用和默认更改
  在TypeScript5。0中,我们已经弃用了以下设置和设置值:target:ES3outnoImplicitUseStrictkeyofStringsOnlysuppressExcessPropertyErrorssuppressImplicitAnyIndexErrorsnoStrictGenericCheckscharsetimportsNotUsedAsValuespreserveValueImportsprependinprojectreferences
  这些配置将继续被允许,直到TypeScript5。5版本,那时它们将被完全删除,然而,如果你使用这些设置,你将收到一个警告。在TypeScript5。0以及未来的版本5。1、5。2、5。3和5。4中,你可以指定ignoreprecations:5。0来消除这些警告。我们还将很快发布一个4。9补丁,允许指定ignoreprecations以允许更顺利的升级。除了弃用之外,我们还更改了一些设置,以更好地改进TypeScript中的跨平台行为。
  newLine,用于控制JavaScript文件中的行结尾,如果不指定,则根据当前操作系统推断。我们认为构建应该尽可能确定,Windows记事本现在支持换行行结束,所以新的默认设置是LF。旧的特定于操作系统的推理行为不再可用。
  forceConsistentCasingInFileNames,这确保了在一个项目中所有对相同文件名的引用都同意使用大小写,现在默认为true。这可以帮助捕获在不区分大小写的文件系统上编写的代码差异问题。
  您可以留下反馈并查看关于5。0弃用的跟踪问题的更多信息接下来是什么?
  TypeScript5。0正在成为一个伟大的版本。在接下来的几周里,我们将专注于bug修复、稳定性和优化即将发布的候选版本,然后是第一个稳定版本。
  和往常一样,关于我们的发行版的细节(包括目标日期!)可以在TypeScript5。0迭代计划中找到。我们希望迭代计划使TypeScript5。0更容易围绕您和您的团队的时间表进行测试!
  我们也希望TypeScript5。0Beta版能带来很多你期待已久的新功能。让我们的beta版本(或我们的夜间构建)今天尝试一下,让我们知道你的想法!

世界杯最新积分战报5个死亡之组西班牙克罗地领跑德国垫底日本第2北京时间11月28日凌晨,2022卡塔尔世界杯第2轮再进行了2个小组4场比赛的争夺。经过一番鏖战,德国11绝平西班牙,克罗地亚41大胜加拿大,哥斯达黎加10绝杀日本,摩洛哥20完胜库里25118追梦19分11助,勇士单节47分大胜森林狼勇士在库汤追三巨头引领下打出招牌进攻,单节轰下47分,最终137114轻取森林狼,拿下三连胜,11胜10负反超森林狼,升上西部第9。库里25分11篮板8助攻,汤普森21分,格林19我们互为旅伴,途经软弱孤独和恐惧没有起始,没有结束我们互为旅伴,途经软弱孤独和恐惧没有起始,没有结束唯存无尽的中途,只能一往无前有句话叫做有信无智,长愚痴,就是说盲目而缺乏智慧的信仰会使人偏执一端,越来越固执,越来越狂热。所以信仰冬天小时候的上学是幸福的冬日生活打卡季冬日里的童年记忆你现在还有冬天的感觉了吗?还记得冬天小时候的上学路吗?自从工作后,过年的气氛慢慢消失了,唯一不消失的是过年一定要回家,不管多么远都要回到父母的身边,回尊重人的最高境界,获得他人的认同周国平说一个有人格和尊严的人,必定懂得尊重他人的人格,同样,如果你侮辱他人,就等于侮辱了自己。人与人之间,最重要的就是相互尊重,尊重他人不仅是做人的基本教养,也是对自己最大的尊重。情感语录在这世界上,只有那快乐的男人才能使自己的女人更幸福,男人是一家之主,自己快乐肯定会给家人带来快乐气氛,人活着就是以开心为主,遇到了困难都是开心面对,家人才感觉不是什么大不了的事情,走过那些阳光灿烂的日子有些时候,我们把匆忙当做生活的主旋律,把匆忙当成生活的打开方式。好像让自己忙起来,便治愈了忧伤安慰了过往。其实不然,忙起来只是暂时搁置了忧伤,忙起来,只是暂时排解了忧伤。忧伤还在那当时青春年少我们相遇太早第一次读到小说致青春时,我还在上大学。我们的心比天高,我们从大学到工作生活的热爱,就像当年我们心中的一盏灯塔,描绘着我们未来生活的图景。心怡舞的话伤了他的心,杨玏扮演的是陈孝正本来十二月朋友圈晚安心语文案,精彩入心,精致走心2022年的最后一个月,善待时光,善待自己。余下的日子里,忙碌中记得照顾好自己!给自己多一些掌声,多一些微笑!珍惜这最后一个月的时光,愿这一年的付出,都在最后的时光里绽放辉煌!晚安为什么我们老是觉得不开心你也是一个容易不开心的人吗?我很喜欢別生气嘛书中的这句话大部分的烦恼,都來自于自己太在乎了。不过到底是在乎什么呢?人为什么那么容易有烦恼,导致自己不开心呢?以下,我摘取书中六個我很现在的我们到底要不要努力了?大家发现没有,一些人通过努力成功了,就会认为其他人不成功都是因为不够努力。这种观念实在过于狭隘,如果光靠努力就行的话,古代哪还会有那么多壮志未酬,郁郁不得志的诗人文豪,需要借诗词歌
首次一城双馆第106届糖酒会开幕11月10日,为期三天的第106届全国糖酒商品交易会在成都开幕。本届糖酒会首次以一城双馆形式举办,同时使用西博城和世纪城新会展中心全部可用室内展馆办展。有来自30多个国家和地区,超鄂尔多斯动物园将升级!总投资3182万元鄂尔多斯野生动物园旅游基础设施建设项目可行性研究报告获批近日,鄂尔多斯市发改委以鄂发改审批发202246号文件批复了鄂尔多斯野生动物园旅游基础设施建设项目可行性研究报告。项目在鄂尔她去明月山温汤温泉泡温泉,竟然捡到了一个足金手镯卢姐和丈夫都是事业单位退下来的老干部,生活条件也比较优越,她有个爱好就是喜欢泡温泉,天然温暖的泉水里,会含有大量的对身体有益的微量元素,不仅美容美体,也具有很好的养生作用特别是冬天北京昨日新增本土6454,含社会面4例11月10日0时至24时,北京新增64例本土确诊病例和54例无症状感染者(含4例无症状感染者转确诊病例,其中59例已通报),110例隔离观察人员4例社会面筛查人员,无新增疑似病例无山东高新技术企业谁更强?科技领军企业和首批科技小巨人名单发布11月9日,在山东省科技厅指导下,山东省科学院情报研究所山东省创新发展研究院在济南联合举行2022年度山东省科技领军企业和首批科技小巨人企业名单发布会,向社会发布了200家科技领军确认星际访客?外星人这个称谓相信大家都不会陌生,我们通过影视书籍或多或少都了解过,外星人到底是否存在,至今争论不休。近日美国哈佛大学天文学家在最新一期天体物理学杂志发表论文称。他们已经证实,20把德国想得太好?朔尔茨刚回国就变脸,中企收购计划遭敲打作者战忽速递虽然我国变得逐渐强大,中国企业走向海外的步子一天比一天迈得大,但由于美国提倡地缘和大国竞争,使得中国企业在海外拓展市场收购计划屡屡受挫。前不久,加拿大响应美国号召禁止我公募基金前三季度亏损1。57万亿元剧烈波动下的基金众生相2月份刚买上没多久就开始亏,眼看着好转,结果三季度又开跌了!市南区的刘女士刚买基金不到一年,就经历了基金市场的持续剧烈波动。特别是三季度以来,A股市场持续调整,震荡行情令不少基金产电视剧天道中音箱系统原理和配置相信很多音箱发烧友都是因为一部影视剧接触到音箱,步入到追求完美声音的旅途中,不断探索和思考。但是很多萌新看完电视剧也完全搞不清楚电视剧主角这套音箱的工作原理和具体器材品牌。现实中也房地产是理财产品房地产是富人更富,穷人更贫。我刚才和老头儿谈了房地产。像我们的老板。身价几万,几千万的人。人家有钱没处花了。买几套房子?当时买的时候是8000块钱。现在都涨到1500016000了你有没有觉得人到中年朋友少了,有些朋友的告别都是静悄悄的文王小二人与人相识,很多时候我们归结于缘分。可是,缘分不一定能一直青睐两个人。一个网友发表了一篇帖子,或许是纪念,或许是不解。她有一个相交了十几年的好友。关系好到不允许任何人说彼此
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网