说明:目前网上还没有最新的TypeScript官方文档的中文翻译,所以才有这样的翻译计划。因为本人也是TypeScript的初学者,不能保证翻译100%准确。如有错误,请在评论区指出;翻译内容:暂定翻译内容为TypeScriptHandbook,其他部分翻译文档稍后补充;项目地址:TypeScript-Doc-Zh,如果对你有帮助,可以点个star~本章官方文档地址:TemplateLiteralTypestemplateliteraltypetemplateliteraltype建立在stringliteraltype的基础上,而可以通过联合类型字符串扩展为多个字符。它的语法与JavaScript中的模板字符串相同,但用于表示TypeScript中的类型。当与具体文字类型一起使用时,模板文字连接其内容以生成新的字符串文字类型。typeWorld='world';typeGreeting=`hello${World}`;^//typeGreeting='helloworld'在模板字面量的插值位置使用联合类型时,得到的类型是联合类型每个成员可以表示的字符串字面量的集合:typeEmailLocaleIDs="welcome_email"|“email_heading”;类型FooterLocaleIDs=“footer_title”|“footer_sendoff”;输入AllLocaleIDs=`${EmailLocaleIDs|FooterLocaleIDs}_id`;^//输入AllLocaleIDs="welcome_email_id"|“email_heading_id”|“footer_title_id”|"footer_sendoff_id"如果模板字面量有多个插值位置,那么会在每个位置的联合类型之间进行叉积运算,得到最终的类型:typeAllLocaleIDs=`${EmailLocaleIDs|FooterLocaleIDs}_id`;输入Lang="en"|“贾”|“点”;输入LocaleMessageIDs=`${Lang}_${AllLocaleIDs}`;^//输入LocaleMessageIDs="en_welcome_email_id"|"en_email_heading_id"|"en_footer_title_id"|“en_footer_sendoff_id”|“ja_welcome_email_id”|“ja_email_heading_id”|“ja_footer_title_id”|“ja_footer_sendoff_id”|“pt_welcome_email_id”|“pt_email_heading_id”|“pt_footer_title_id”|“pt_footer_sendoff_id"对于较大的字符串联合类型,我们建议您提前生成它们。对于较小的字符串联合类型,您可以使用上面示例中的方法来生成它们。字符串联合类型模板字面量在类型中的强度是它可以根据类型中已有的信息定义一个新的字符串。假设有一个makeWatchedObject函数,可以为传入的对象添加一个on方法。在JavaScript中,函数调用就像:makeWatchedObject(baseObject)。其中,传入的对象参数类似如下:constpassedObject={firstName:'Saoirse',lastName:'Ronan',age:26,};要添加到对象的on方法会接受两个参数,一个是eventName(String),一个是callBack(回调函数)。eventName的形式类似于attributeInThePassedObject+'Changed'。比如传入的对象有一个firstName属性,那么就会对应的有一个eventName叫firstNameChanged。而thecallBack回调函数,被调用时,会:接受一个参数,参数的类型与attributeInThePassedObject的类型相关联。比如firstName的类型是string,那么firstNameChanged事件对应的回调函数在调用Parameters的时候也期望接受一个string类型。类似地,与年龄关联的事件回调函数在调用时应该接受一个类型为number的参数。返回值类型为void(方便示例说明)。on()的简单函数签名可能是这样的:on(eventName:string,callBack:(newValue:any)=>void)。但是,从上面的描述中,我们发现代码中仍然需要实现非常重要的类型约束。模板文字类型正好可以帮助我们做到这一点。constperson=makeWatchedObject({firstName:"Saoirse",lastName:"Ronan",age:26,});//makeWatchedObject函数向匿名对象添加一个on方法person.on("firstNameChanged",(newValue)=>{console.log(`firstNamewaschangedto${newValue}!`);});注意on监听的事件是“firstNameChanged”,不是“firstName”。如果我们想确保符合条件的事件名称集受联合类型的对象属性名称(末尾附加“Changed”)的约束,那么我们简单的on()方法需要进一步改进。虽然我们可以在JavaScript中轻松实现这种效果,比如使用Object.keys(passedObject).map(x=>${x}Changed),但是类型系统中的模板字面量也提供了类似的操作字符串的方法:typePropEventSource={on(eventName:`${string&keyofType}Changed`,callback:(newValue:any)=>void):void;};//创建一个带有on方法的监听对象,从而监听对象属性的变化declarefunctionmakeWatchedObject(obj:Type):Type&PropEventSource;这样,当传入错误的参数时,TypeScript会抛出错误:constperson=makeWatchedObject({firstName:"Saoirse",lastName:"Ronan",age:26});person.on("firstNameChanged",()=>{});//防止常见的人为错误(错误地使用对象的属性名称而不是事件名称)person.on("firstName",()=>{});//类型'"firstName"'的参数不可赋值到'"firstNameChanged"类型的参数|“lastNameChanged”|“年龄改变了”。//打字错误person.on("firstNameChanged",()=>{});//类型“firstNameChanged”的参数不能分配给类型“firstNameChanged”的参数|“lastNameChanged”|“年龄改变了”。模板文字的推断当输入对象提供的信息firstName发生变化时(触发firstNameChanged事件),我们希望回调函数接受一个字符串类型的参数。同样,当年龄发生变化时,对应的回调函数也会接受一个number类型的参数。但是现在,我们只使用any作为回调函数参数的类型。这里又需要使用模板字面量类型,可以保证属性的数据类型和属性对应的回调函数的参数类型一致。这样做的关键在于,我们可以使用带有泛型的函数来确保:第一个参数中的字面量可以被捕获为字面量类型泛型的有效属性形成一个可以验证的联合类型捕获的字面量类型是否为可以通过通用结构中的索引访问联合类型的成员,以查看已验证属性的类型。此类型信息可进一步用于确保回调函数的参数也是同一类型typePropEventSource={on(eventName:`${Key}Changed`,callback:(newValue:Type[Key])=>void):void;}declarefunctionmakeWatchedObject(obj:Type):Type&PropEventSource;constperson=makeWatchedObject({firstName:"Saoirse",lastName:“罗南”,年龄:26});person.on("firstNameChanged",newName=>{^//(parameter)newName:stringconsole.log(`newnameis${newName.toUpperCase()}`);});person.on("ageChanged",newAge=>{^//(parameter)newAge:numberif(newAge<0){console.warn("warning!negativeage");}})这里我们创建一个泛型方法.当开发人员使用字符串“firstNameChanged”调用on方法时,TypeScript将尝试推断Key的正确类型。具体来说,它将Key与“Changed”之前的部分进行匹配,并推导出字符串“firstName”。一旦TypeScript推断完成,on方法就可以取出原始对象的firstName属性的类型——即字符串类型。同理,通过“ageChanged”调用方法时,TypeScript也会发现age属性的类型是number。推理可以以多种不同的方式组合,并且通常用于解构字符串并以不同的方式重建它们。内置字符串操作类型为了方便操作字符串,TypeScript引入了一些相关类型。出于性能原因,这些类型内置到编译器中,并且无法在TypeScript附带的.d.ts文件中找到。Uppercase将字符串中的每个字符转换为大写。示例:typeGreeting='Hello,world'typeShoutyGreeting=Uppercase^//typeShoutyGreeting='HELLO,WORLD'typeASCIICacheKey=`ID-${Uppercase}`typeMainID=ASCIICacheKey<'my_app'>^//typeMainID='ID-MY_APP'Lowercase将字符串中的每个字符转换为小写。示例:typeGreeting="Hello,world"typeQuietGreeting=Lowercase^//typeQuietGreeting="hello,world"typeASCIICacheKey=`id-${Lowercase}`typeMainID=ASCIICacheKey<"MY_APP">^//typeMainID="id-my_app"Capitalize将字符串的第一个字符转换为大写。示例:typeLowercaseGreeting='hello,world';typeGreeting=Capitalize;^//typeGreeting='Hello,world'Uncapitalize将字符串的第一个字符转换为小写。示例:键入UppercaseGreeting='HELLOWORLD';键入UncomfortableGreeting=Uncapitalize;^//typeUncomfortableGreeting="hELLOWORLD"关于内置字符串操作类型的一些技术细节:从TypeScript4.1开始,这些内置实现直接使用JavaScript的字符串运行时函数进行操作,无法实现本地化识别。函数applyStringMapping(symbol:Symbol,str:string){switch(intrinsicTypeKinds.get(symbol.escapedNameasstring)){caseIntrinsicTypeKind.Uppercase:returnstr.toUpperCase();案例IntrinsicTypeKind.Lowercase:returnstr.toLowerCase();caseIntrinsicTypeKind.Capitalize:returnstr.charAt(0).toUpperCase()+str.slice(1);案例IntrinsicTypeKind.Uncapitalize:returnstr.charAt(0).toLowerCase()+str.slice(1);}返回海峡;}