的文献看完这篇文章,你应该能理解下面代码的含义:interfaceArray{concat(...items:Array):T[];reduce(callback:(state:U,element:T,index:number,array:T[])=>U,firstState?:U):U;···}如果你认为这段代码很隐晦——那我同意你的看法。但是(我希望证明)这些符号相对容易学习。一旦理解了它们,您就可以立即全面准确地理解代码,因此您无需阅读冗长的英文说明。运行代码示例TypeScript有一个在线运行时。要获得最全面的信息,您应该打开“选项”菜单中的所有选项。这相当于在--strict模式下运行TypeScript编译器。关于类型检查的详细说明我总是喜欢在使用TypeScript时打开--strict开关。没有它,程序可能会更容易编写,但您也会失去静态类型检查的好处。目前此设置启用以下子设置:--noImplicitAny:如果TypeScript无法推断类型,则必须指定此项。这主要用于函数和方法的参数:使用此设置,您必须对它们进行注释。--noImplicitThis:如果this的类型不清楚,会有提示。--alwaysStrict:尽可能使用JavaScript的严格模式。--strictNullChecks:null不属于任何类型(除了它自己的类型null),如果它是一个可接受的值,则必须明确指定。--strictFunctionTypes:对函数类型进行更严格的检查。--strictPropertyInitialization:如果属性的值不能是undefined,那么它必须在构造函数中初始化。更多信息:TypeScript手册中的“编译器选项”一章。类型在本文中,我们将类型视为值的集合。JavaScript语言(不是TypeScript!)有7种类型:未定义:第一个元素未定义的集合。Null:具有元素“null”的集合。布尔值:具有两个元素false和true的集合。数:所有数的集合。字符串:所有字符串的集合。符号:所有符号的集合。对象:所有对象(包括函数和数组)的集合。所有这些类型都是动态的:它们可以在运行时使用。TypeScript为JavaScript带来了一个额外的层:静态类型。这些仅在编译或类型检查源代码时存在。每个存储位置(变量或属性)都有一个预测其动态值的静态类型。类型检查确保这些预测得到满足。还有很多东西可以静态检查(无需运行代码)。例如,如果函数f(x)的参数x是静态类型number,则函数调用f('abc')是非法的,因为参数'abc'是错误的静态类型。类型注解在变量名后以冒号开头类型注解:冒号后的类型签名用于描述变量可以接受的值。例如,告诉TypeScript变量“x”只能存储数字:letx:number;您可能想知道用undefined初始化x是否违反了静态类型。TypeScript不允许这样做,因为x在赋值之前不允许被操作。类型推断尽管TypeScript中的每个存储位置都有一个静态类型,但您不必总是明确指定它。TypeScript通常可以推断其类型。例如,如果你写这行代码:letx=123;那么TypeScript会推断出x的静态类型是数字。出现在类型注释中冒号之后的类型描述是所谓的类型表达式。这些范围从简单到复杂,创建如下。原始类型是有效的类型表达式:静态类型对应JavaScript动态类型:-`undefined`,`null`-`boolean`,`number`,`string`-`symbol`-`object`注意:undefined的值是与Typeundefined(取决于位置)TypeScript特定类型相同:Array(技术上不是JS中的类型)any(所有值的类型)等。其他类型注意“undefinedasvalue”和“undefinedastype”写为undefined.解释为值或类型,具体取决于您使用它的位置。null也是如此。您可以通过将基本类型与类型运算符组合来创建更多类型的表达式,这有点像使用运算符并集(∪)和交集(∪)来组合集合。以下是TypeScript提供的一些类型运算符。数组类型数组在JavaScript中扮演两个角色(有时两者兼而有之):列表:所有元素都具有相同的类型。阵列的长度各不相同。元组:数组的长度是固定的。元素不一定是同一类型。ArrayasalistArrayarr用作列表有两种方式,它的元素都是数字:letarr:number[]=[];letarr:Array=[];通常如果有赋值,TypeScript可以推断出变量的类型。在这种情况下,您实际上必须帮助它确定类型,因为在使用空数组时它无法确定元素的类型。稍后我们将回到尖括号表示法(Array)。Arraysastuples如果要将二维坐标点存储在数组中,可以将此数组用作元组。它看起来像这样:letpoint:[number,number]=[7,5];在这种情况下,您不需要类型注释。另一个例子是Object.entries(obj)的返回值:一个带有[key,value]对的数组,描述了obj的每个属性。>Object.entries({a:1,b:2})[['a',1],['b',2]]Object.entries()的返回值类型为:Array<[string,any]>函数类型下面是函数类型的例子:(num:number)=>string这种类型是一个接受数字类型参数并返回字符串的函数。在类型注释中使用此类型(String在这里是一个函数)的示例:constfunc:(num:number)=>string=String;同样,我们这里一般不使用类型注解,因为TypeScript知道String的类型,所以可以推断出func的类型。下面的代码是一个比较现实的例子:functionstringify123(callback:(num:number)=>string){returncallback(123);}由于我们使用函数类型来描述stringify123()的参数回调,所以TypeScript拒绝了下面的函数称呼。f(数字);但它接受以下函数调用:f(String);函数声明的返回类型注释函数的所有参数是一个好习惯。您还可以指定返回类型(但TypeScript非常擅长推断它):functionstringify123(callback:(num:number)=>string):string{constnum=123;returncallback(num);}特殊返回类型voidvoid是函数特殊返回值类型:它告诉TypeScript函数总是返回undefined(显式或隐式):'abc'}//error可选参数标识后的问号表示该参数是可选的。例如:functionstringify123(callback?:(num:number)=>string){constnum=123;if(callback){returncallback(num);//(A)}returnString(num);}在--strict模式下运行TypeScript,如果在先前检查期间未省略回调,它只允许您在A行进行函数调用。参数默认值TypeScript支持ES6参数默认值:functioncreatePoint(x=0,y=0){return[x,y];}默认值可以让参数可选。通常可以省略类型注释,因为TypeScript可以推断类型。例如,它可以推断出x和y都是数字类型。如果要添加类型注解,应该这样写:functioncreatePoint(x:number=0,y:number=0){return[x,y];}resttypeTypeScript参数定义也可以使用ES6restoperator.对应参数的类型必须是数组:functionjoinNumbers(...nums:number[]):string{returnnums.join('-');}joinNumbers(1,2,3);//'1-2-3'Union在JavaScript中,有时变量是几种类型之一。为了描述这些变量,可以使用联合类型。例如,在下面的代码中,x的类型为null或number:letx=null;x=123;x的类型可以描述为null|number:letx:null|number=null;x=123;类型表达式s|t的结果是集合论意义上的类型s和t的并集(两个集合,如我们之前所见)。让我们重写函数stringify123():这次我们不希望参数回调是可选的。它应该总是被调用。如果调用者不想传入函数,则必须显式传递null。实现如下。functionstringify123(callback:null|((num:number)=>string)){constnum=123;if(callback){//(A)returncallback(123);//(B)}returnString(num);}请请注意,在B行调用函数之前,我们必须再次检查回调是否真的是一个函数(A行)。如果没有勾选,TypeScript会报错。Optional非常类似于undefined|TOptionalparametersoftypeT和parameterstypeundefined|T。(也适用于可选属性。)主要区别在于您可以省略可选参数:functionf1(x?:number){}f1();//OKf1(undefined);//OKf1(123);//OK但是你可以'要省略类型的参数但不能省略undefined|T类型的参数:functionf2(x:undefined|number){}f2();//errorf2(undefined);//OKf2(123);//OK值null和undefined通常不包含在类型中在许多编程语言中,null是所有类型的一部分。比如Java中只要参数类型是String,你可以传null,Java就不会报错。相反,在TypeScript中,undefined和null由单独的不相交类型处理。如果你想让它们工作,必须有一个像undefined|string和null|string这样的类型联合。对象与数组类似,对象在JavaScript中扮演两个角色(有时是混合的和/或更动态的):记录:在开发时已知的固定数量的属性。每个属性可以有不同的类型。字典:在开发时名称未知的任意数量的属性。所有属性键(字符串和/或符号)都具有相同的类型,属性值也是如此。我们将在本文中忽略对象作为字典。顺便说一句,无论如何,地图通常是比字典更好的选择。通过接口对象作为记录接口描述对象作为记录。例如:interfacePoint{x:number;y:number;}TypeScript类型系统的一大优势是它的结构,而不是它的命名。也就是说,接口Point可以匹配适当结构的所有对象:functionpointToString(p:Point){return`(${p.x},${p.y})`;}pointToString({x:5,y:7});//'(5,7)'相比之下,Java的标称类型系统需要类来实现接口。可选属性如果一个属性可以省略,在它的名字后面加一个问号:interfacePerson{name:string;company?:string;}Methods接口也可以包含方法:interfacePoint{x:number;y:number;distance(other:point):number;}类型变量和泛型类型使用静态类型,可以有两个层次:值存在于对象层次。类型存在于元级别。同理:普通变量定义在对象层之上。类型变量存在于元级别之上。它们是值类型的变量。普通变量通过const、let等引入。类型变量通过尖括号(<>)引入。例如,下面的代码包含一个类型变量T,通过引入。interfaceStack{push(x:T):void;pop():T;}您可以看到类型参数T在Stack的主体中出现了两次。因此,接口可以直观地理解如下:Stack是一堆值,所有值都是给定类型T。凡是提到Stack,就一定要写T,接下来我们就来看看怎么用吧。.push()方法接受T类型的值。.pop()方法返回类型为T的值。如果使用Stack,则必须为T分配一个类型。以下代码显示了一个虚拟堆栈,其唯一目的是匹配接口。constdummyStack:Stack={push(x:number){},pop(){return123},};示例:TypeScript中mapmap的定义。例如:constmyMap:Map=newMap([[false,'no'],[true,'yes'],]);函数的类型变量函数(和方法)也可以引入类型变量:functionid(x:T):T{returnx;}您可以按如下方式使用此函数。编号<编号>(123);由于类型推断,类型参数也可以省略:id(123);传递类型参数函数可以将其他类型参数传递给接口、类等:functionfillArray(len:number,elem:T){returnnewArray(len).fill(elem);}类型变量T出现三个这段代码中的次数:fillArray:引入类型变量elem:T:使用类型变量,从参数中选择它。Array:将T传递给Array的构造函数。这意味着:我们不必明确指定Array的类型T-它是从参数elem中推断出来的:constarr=fillArray(3,'*');//Inferredtype:string[]总结让我们用前面学到的知识来理解你一开始看到的代码:interfaceArray{concat(...items:Array):T[];reduce(callback:(state:U,element:T,index:number,array:T[])=>U,firstState?:U):U;···}这是一个Array接口,其元素type为T,无论何时使用Thisinterface必须填写:方法.concat()具有零个或多个参数(通过rest运算符定义)。这些参数中的每一个都具有类型T[]|T。也就是说,它是一个类型为T的数组或T的一个值。方法.reduce()引入了它自己的类型变量U。U表示下面的实体都是同一个类型(不用指定,自动推断):callback()的参数state(是一个函数)state是callback()的参数(是一个function)callback()的结果callback()returnreduce()可选参数firstState.reduce()reduce()returncallback的结果也会得到一个元素参数,其类型与Array元素的类型T相同,参数索引为anumber,参数数组为T的值。