TypeScript是一种类型化语言,允许您指定变量、函数参数、返回值和对象属性的类型。您可以将本文视为带有示例的TypeScript高级打字备忘单让我们开始吧!交集类型交集类型是一种将多种类型组合为一种的方法。这意味着您可以将给定的类型A与类型B或更多组合起来,并获得具有所有属性的单一类型。typeLeftType={id:number;left:string;};typeRightType={id:number;right:string;};typeIntersectionType=LeftType&RightType;functionshowType(args:IntersectionType){console.log(args);}showType({id:1,left:'test',right:'test'});//Output:{id:1,left:"test",right:"test"}如你所见,IntersectionType结合了两种类型——LeftType和RightType,并使用&号组成十字型。UnionTypes(联合类型)联合类型允许你给同一个变量不同的类型typeUnionType=string|number;functionshowType(arg:UnionType){console.log(arg);}showType('test');//输出:testshowType(7);//Output:7函数showType是一个联合类型函数,接受字符串或数字作为参数。泛型类型泛型类型是重用给定类型的一部分的一种方式。它有助于捕获作为参数传递的类型T。优点:创建可重用的函数,一个函数可以支持多种类型的数据。这样开发者就可以使用泛型函数functionshowType(args:T){console.log(args);}showType('test');//Output:"test"showType(1);//Output:1如何创建泛型:需要使用<>并传入T(名称可以自定义)作为参数。在🌰上面的栗子,我们在showType中添加了一个类型变量T。T帮我们捕获用户传入的参数类型(例如:数字/字符串),然后我们就可以使用这个类型。我们称showType函数为泛型函数,因为它可以应用于多种类型的泛型接口}showType({id:1,name:'test'});//输出:{id:1,name:"test"}functionshowTypeTwo(args:GenericType){console.log(args);}showTypeTwo({id:1,name:4});//Output:{id:1,name:4}在上面的栗子中,声明了一个GenericType接口,它接受泛型类型T,并使用类型T来约束接口中名称的类型注意:泛型变量约束了整个接口后,在实现A类型时必须指定,所以我们在使用时可以将名称设置为任意类型的值。示例中为字符串或数值多参数泛型类型interfaceGenericType{id:T;name:U;}functionshowType(args:GenericType){console.log(args);}showType({id:1,name:'test'});//输出:{id:1,name:"test"}functionshowTypeTwo(args:GenericType){console.log(args);}showTypeTwo({id:'001',name:['This','is','a','Test']});//输出:{id:"001",name:Array["This","is","a","Test"]}泛型可以接收多个参数在上面的代码中,我们传入了两个参数:T和U,然后将它们作为id、name的类型。也就是说,我们现在可以使用接口并提供不同的类型作为参数。UtilityTypesTypeScript内部也提供了很多方便实用的工具,可以帮助我们更轻松的操作类型。如果要使用它们,则需要将类型传递给<>PartialPartialPartial允许您将类型T的所有属性设为可选。它会添加一个?在每个字段之后。interfacePartialType{id:number;firstName:string;lastName:string;}/*等同于interfacePartialType{id?:numberfirstName?:stringlastName?:string}*/functionshowType(args:Partial){console.log(args);}showType({id:1});//输出:{id:1}showType({firstName:'John',lastName:'Doe'});//输出:{firstName:"John",lastName:"Doe"}上面的代码声明了一个PartialType接口,作为函数showType()的参数类型。为了使所有字段都可选,我们使用Partial关键字并将PartialType类型作为参数传递。RequiredRequired将类型中的所有属性转换为必需的选项({id:1,firstName:'John',lastName:'Doe'});//输出:{id:1,firstName:"John",lastName:"Doe"}showType({id:1});//Error:Type'{id:number:}'missingthefollowingpropertiesfromtype'Required':firstName,lastName在上面的代码中,即使我们在使用接口之前将一些属性设为可选,Required也被添加也使所有属性成为强制性的。如果省略了一些必需的参数,TypeScript将抛出错误。ReadonlyReadonly转换该类型的所有属性,使其不可修改interfaceReadonlyType{id:number;name:string;}functionshowType(args:Readonly){args.id=4;console.log(args);}showType({id:1,name:'Doe'});//Error:Cannotassignto'id'becauseitisaread-onlyproperty.我们使用Readonly使ReadonlyType的属性不可修改。也就是说,如果您尝试为这些字段之一分配新值,则会抛出错误。另外,也可以在指定的属性前面加上关键字readonly,防止它被重新赋值interfaceReadonlyType{readonlyid:number;name:string;}PickPick这个方法可以让你从已有的Select中选择将类型T中的一些属性作为K,从而创建一个新类型,提取类型/接口的一些子集作为新类型T表示要提取的对象K。有一个约束:它必须来自T的所有属性字面量联合类型的新类型/属性必须从K中选择,/**sourceimplementation*FromT,pickasetofpropertieswhosekeysareintheunionK*/typePick={[PinK]:T[P];};interfacePickType{id:number;firstName:string;lastName:string;}functionshowType(args:Pick){console.log(args);}showType({firstName:'John',lastName:'Doe'});//Output:{firstName:"John"}showType({id:3});//Error:Objectliteralmayonlyspecifyknownproperties,and'id'doesnotexistintype'Pick'和我们一起挑前面讨论的工具有点不同,它有两个参数T是要从中选择的元素类型K是要选择的属性(您可以使用联合类型来选择多个字段)OmitOmitOmit起作用与ThePick类型相同,正好相反。不是选择元素,而是从类型T中删除K属性。interfacePickType{id:number;firstName:string;lastName:string;}functionshowType(args:Omit){console.log(args);}showType({id:7});//Output:{id:7}showType({firstName:'John'});//错误:Objectliteralmayonlyspecifyknownproperties,and'firstName'doesnotexistintype'Pick'ExtractExtract进行提取T可以在--takeintersection中分配给U的类型Extract允许您通过选择两种不同类型中的公共属性来构造新类型。也就是说,所有可分配给U的属性都是从T中提取的。>;//输出:上面代码中的"id"其中,FirstType接口和SecondType接口都有id:number属性。因此,通过使用Extract,新类型{id:number}被提取出来。ExcludeExclude--从T中排除可分配给U的类型。与Extract不同,Exclude通过排除两种不同类型中已存在的公共属性来构造新类型。它排除了T中可分配给U的所有字段。interfaceFirstType{id:number;firstName:string;lastName:string;}interfaceSecondType{id:number;address:string;city:string;}typeExcludeExcludeType=Exclude;//Output;"firstName"|"lastName"从上面的代码可以看出,SecondType类型中不存在属性firstName和lastName。通过使用Extract关键字,我们可以获得T中存在但U中不存在的字段。RecordRecord此工具可帮助您为给定类型T构造具有一组属性K的类型。记录非常方便将一种类型的属性映射到另一种类型的属性时。interfaceEmployeeType{id:number;fullname:string;role:string;}letemployees:Record={0:{id:1,fullname:'JohnDoe',role:'Designer'},1:{id:2,fullname:'IbrahimaFall',role:'Developer'},2:{id:3,fullname:'SaraDuckson',role:'Developer'},};//0:{id:1,fullname:"JohnDoe",role:"Designer"},//1:{id:2,fullname:"IbrahimaFall",role:"Developer"},//2:{id:3,fullname:"SaraDuckson",role:"开发人员"}Record以一种相对简单的方式工作。在代码中,它需要一个数字作为类型,这就是为什么我们将0、1和2作为employees变量的键。如果您尝试使用字符串作为属性,则会出现错误,因为属性是由EmployeeType作为具有字段id、fullName和role的对象给出的。NonNullableNonNullable--从TNonNullableType=string|number|null|undefined中移除null和undefined;functionshowType(args:NonNullable){console.log(args);}showType('test');//输出:"test"showType(1);//Output:1showType(null);//错误:Argumentoftype'null'isnotassignabletoparameteroftype'string|number'.showType(undefined);//错误:Argumentoftype'undefined'isnotassignabletoparameteroftype'string|数字'。我们将类型NonNullableType作为参数传递给NonNullable,NonNullable通过排除null和undefined构造一个新类型。也就是说,如果您传递可为null的值,TypeScript将抛出错误。顺便说一句,如果您将--strictNullChecks标志添加到您的tsconfig文件,TypeScript将应用非空检查规则。MappedTypes(映射类型)映射类型允许您从旧类型生成新类型。请注意,前面描述的一些高级类型也是映射类型。如:/*Readonly、Partial和Pick是同态的,而Record不是。因为Record不需要输入类型来复制属性,所以它不是同态的:*/typeReadonly={readonly[PinkeyofT]:T[P];};typePartial={[PinkeyofT]?:T[P];};typePick={[PinK]:T[P];};记录;typeStringMap={[PinkeyofT]:string;};functionshowType(arg:StringMap<{id:number;name:string}>){console.log(arg);}showType({id:1,name:'Test'});//Error:Type'number'isnotassignabletotype'string'.showType({id:'testId',name:'ThisisaTest'});//Output:{id:"testId",name:"ThisisaTest"}StringMap<>会将传入的任何类型转换为字符串。也就是说,如果我们在函数showType()中使用它,接收到的参数必须是一个字符串——否则,TypeScript将引发错误。类型保护类型保护允许您使用运算符检查变量或对象的类型。这是一个条件块,它使用typeof、instanceof或返回类型。Typescript可以保证特定块中的变量是特定类型的。您可以安全地在此块中引用此类型的属性,或调用方法typeofffunctionshowType(x:number|string){if(typeofx==='number'){return`Theresultis${x+x}`;}thrownewError(`Thisoperationcan'tbedoneona${typeofx}`);}showType("I'mnotanumber");//Error:Thisoperationcan'tbedoneonastringshowType(7);//Output:Theresultis14whatcode,有一个正常的JavaScript条件块检查通过typeof接收到的参数的类型。instanceofclassFoo{bar(){return'HelloWorld';}}classBar{baz='123';}functionshowType(arg:Foo|Bar){if(arginstanceofFoo){console.log(arg.bar());returnarg.bar();}thrownewError('Thetypeisnotsupported');}showType(newFoo());//Output:HelloWorldshowType(newBar());//Error:Thetypeisnotsupported和前面的例子一样,这也是一个类型保护,检查receive传入的参数是否是Foo类的一部分,并进行处理。ininterfaceFirstType{x:number;}interfaceSecondType{y:string;}functionshowType(arg:FirstType|SecondType){if('x'inarg){console.log(`Theproperty${arg.x}exists`);return`Theproperty${arg.x}exists`;}thrownewError('Thistypeisnotexpected');}showType({x:7});//Output:Theproperty7existsshowType({y:'ccc'});//错误:什么isThistypeisnotexpected,用于检查参数对象上的属性x是否存在。条件类型条件类型测试两种类型,然后根据测试结果选择其中一种。由条件表达式确定的类型,表示为TextendsU?X:Y,即如果类型T可以赋值给类型U,则结果类型为类型X,否则为类型Y。条件类型使类型不唯一,增加了语言的灵活性。//源码实现typeNonNullable=Textendsnull|undefined?never:T;//NotNull等价于NoneNullable//用法举例typeresType=NonNullable;//string|number上面代码中,NonNullable检查类型是否为null,并根据该类型进行处理。如您所见,它使用了JavaScript三元运算符。