Vue3 TypeScript 快速上手手册_第1页
Vue3 TypeScript 快速上手手册_第2页
Vue3 TypeScript 快速上手手册_第3页
Vue3 TypeScript 快速上手手册_第4页
Vue3 TypeScript 快速上手手册_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Vue3+TypeScript?看这一篇就够了

1、Typescript快速上手

1.1初识TypeScript

Typescript

StronglyTyped

TypeScript的介绍

TypeScript是一种由微软开发的开源、跨平台的编程语言。它是JavaScript的超集,最终会被编译为JavaScript代码,

2012年10月,微软发布了首个公开版本的TypeScript,2013年6月19日,在经历了一个预览版之后微软正式发布了正式版

TypeScriptTypeScript的作者是安德斯・海尔斯伯格,C#的首席架构师.它是开源和跨平台的编程语言.

TypeScript扩展了JavaScript的语法,所以任何现有的JavaScript程序可以运行在TypeScript环境中。

TypeScript是为大型应用的开发而设计,并且可以编译为JavaScript。

TypeScript是JavaScript的一个超集,主要提供了类型系统和对ES6+的支持*"它由Microsoft开发,代码开源于GitHub上

TypeScript是JavaScript的一个超集,主要提供了类型系统和对ES6+的支持,它由Microsoft开发,代码上

TypeScript的特点

TypeScript主要有3大特点:

-始于JavaScript,归于JavaScript

TypeScript可以编译出纯净、简洁的JavaScript代码,并且可以运行在任何浏览器上、Node.js环境中和任何支持ECMAScript3(

或更高版本)的JavaScript引擎中.

•强大的类型系统

类型系统允许JavaScript开发者在开发JavaScript应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构.

•先进的JavaScript

TypeScript提供最新的和不断发展的JavaScript特性,包括那些来自2015年的ECMAScript和未来的提案中的特性,比如异步功能

和Decorators,以帮助建立健壮的组件.

总结

Typescript在社区的流行度越来越高,它非常适用于一些大型项目,也非常适用于一些基础库,极大地帮助我们提升了开发效率和体验.

1.2安装Typescript

命令行运行如下命令,全局安装Typescript:

npminstall-gtypescript

安装完成后,在控制台运行如下命令,检杳安装是否成功(3.x):

tsc-V

1.3.第一个TypeScript

编写TS程序

src/helloworld,ts

functiongreeteriperson){

return'Hello,'+person

}

letuser='Yee'

consoie.iog(greeter(user)

手动编译代码

我们使用了.ts扩展名,但是这段代码仅仅是JavaScript而已。

在命令行上,运行TypeScript编译器:

tschelloworld.ts

输出结果为一个helloworld.js文件,它包含了和输入文件中相同的JavsScript代码.

在命令行上,通过Node.js运行这段代码:

nodehelloworld.js

控制台输出:

Hello,Yee

VsCode自动编译

1).生成配省文件tsconfig.json

tsc-init

2).修改stconfig.json配置

"outDir"

"strict":false,

3).启动监视任务:

终端->运行任务->监视tsconfig.json

类型注解

接下来让我们看看TypeScript工具带来的高级功能.给person函数的参数添加:string类型注解,如下:

functiongreeter(person:string){

return'Hello,'+person

letuser='Yee'

console.log(greeteruser)

Typescript里的类型注解是一种轻量级的为函数或变量添加约束的方式.在这个例子里,我们希望greeter函数接收一个字符串参数。

然后尝试把greeter的调用改成传入一个数组:

functiongreeter(personstring){

return'Hello,'+person

)

letuser=[0.1,2]

console.log(greeter(user)

重新编译,你会看到产生了一个错误:

errorTS2345:Argumentoftype'number。'isnotassignabletoparameteroftype'string'.

类似地,尝试删除greeter调用的所有参数.TypeScript会告诉你使用了非期望个数的参数调用了这个函数。在这两种情

况中,Typescript提供了静态的代码分析,它可以分析代码结构和提供的类型注解。

要注意的是尽管有错误,greeterJs文件还是被创建了.就算你的代码里有错误,你仍然可以使用TypeScript.但在这种情况

下,Typescript会警告你代码可能不会按预期执行.

接口

让我们继续扩展这个示例应用.这里我们使用接口来描述一个拥有firstName和lastName字段的对象.在TypeScript里,只在两个类

型内部的结构兼容,那么这两个类型就是兼容的.这就允许我们在实现接口时候只要保证包含了接口要求的结构就可以,而不必明确地

使用implements语句。

interfacePerson{

firstName:string

lastNamestring

)

functiongreeter(personPerson{

return'Hello,'+personfirstName+''+personlastName

}

letuser={

firstName:'Yee',

lastName:'Huang'

)

console.log(oreeter(user))

最后,让我们使用类来改写这个例子.TypeScript支持JavaScript的新特性,比如支持基于类的面向对象编程。

让我们创建一个User类,它带有一个构造函数和一些公共字段.因为类的字段包含了接口所需要的字段,所以他们能很好的兼容。

还要注意的是,我在类的声明上会注明所有的成员变量,这样比较一目了然。

classUser|

fullNamestring

firstName:string

laslNanie:siring

constructor(firstName:string,lastNamestring){

thisfirstName=firstName

thislasthame=lastName

thisfullName=firstName+"+lastName

}

}

interfacePerson{

firstName:string

lastName:string

}

functiongreeteripersonPerson{

return'Hello,'+personfirstName+''+personlastName

)

letuser=newUserYee','Huang')

console.log(greeter(user)

重新运行tscgreeter.ts,你会看到TypeScript里的类只是一个语法糖,本质上还是JavaScript函数的实现。

总结

到这里,你已经对Typescript有了一个大致的印象,那么下一章让我们来一起学习TypeScript的一些常用语法吧。

1.4使用webpack打包TS

下载依赖

yarnadd-Dtypescript

yarnadd-Dwebpackwebpack-cli

yarnadd-Dwebpack-dev-server

yarnadd-Dhtml-webpack-pluginclean-webpack-plugin

yarnadd-Dts-loader

yarnadd-Dcross-env

入口JS:src/main.ts

/import'./01_helloworld'

documentwrtte('HelloWebpackTS!')

index页面:public/index.html

<!DOCTYPEhtml>

<htmllang="en">

<head>

<metacharset="UTF-8">

<metaname="viewport"content="width=device-width,initial-scale=1.0">

<metahttp-equiv="X-UA-Compatible"content="ie=edge">

<title:webpack&TStitle>

</head>

<body>

<.body>

const{CleanWebpackPlugin:requireCclean-webpack-plugin")

constHtmlWebpackPlugin=require('html-webpack-plugin')

constpath=require('path')

constisProd=processenv.NODE_ENV==='production'

functionresolve(dir){

returnpathresolvetdirname'dir)

}

moduleexports-{

modeisProd?'production':'development'.

entry:{

app'Jsrcmain.ts'

},

output:{

pathresolve('dist'),

filename[name].[contenthash:8].js'

},

module{

rules[

(

testA.tsx?$/,

use'ts-loader',

include:[resolveCsrc')]

}

]

},

plugins[

newCleanWebpackPlugin({

}),

newHtmlWebpackPlugin

template:'.public'index.html'

))

].

resolve{

extensions(*.ts','.tsx','jsl

},

devtoolisProd?'cheap-module-source-map':'cheap-module-eval-source-map',

devServer{

host'localhost*,/主机名

stats:,errors-only'J打包R志输出输出错误侑息

port8081.

opentrue

},

}

配置打包命令

"dev":ucross-envNODE_ENV=developmentwebpack-dev-server-configbuild/webpack.config.js",

"build":"cross-envNODE_ENV=productionwebpack-configbuild'webpack.config.js"

运行与打包

2、Typescript常用语法

2.1基础类型

Typescript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

布尔值

最基本的数据类型就是简单的true/false值,在JavaScript和TypeScript里叫做boolean(其它语言中也一样).

letisDoneboolean=false;

isDone=true:

/isDone=2/error

数字

和JavaScript一样,TypeScript里的所有数字都是浮点数。这些浮点数的类型是number,除了支持十进制和十六进制字

面量,TypeScript还支持ECMAScript2015中引入的二进制和八进制字面量.

leta1:number=10升迸制

leta2:number=Ob1010二进制

leta3:number=Oo12,八进制

leta4:number=Oxa"六进制

字符串

JavaScript程序的另一项基本操作是处理网页或服务器端的文本数据.像其它语言里一样,我们使用string表示文本数据类型.

和JavaScript一样,可以使用双引号(")或单引号(*)表示字符串。

letnamestring='tom'

name:'jack'

/name=12/error

letagenumber=12

constinfo=Mynameis${name;,Iam${age}yearsold!'

undefined和null

TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null.它们的本身的类型用处不是很大:

letuundefined:undefined

letn:null=null

默认情况下null和undefined是所有类型的子类型。就是说你可以把null和undefined赋值给number类型的变量.

数组

TypeScript像JavaScript一样可以操作数组元素.有两种方式可以定义数组。第一种,可以在元素类型后面接上[],表示由此类型元素

组成的一个数组:

letlistlnumber口=[1,2,3]

第二种方式是使用数组泛型,Arrayv元素类型〉:

letIlst2Array<number>=[1,2.3]

元组Tuple

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为string和number类型的

元组。

lettl:[string,number]

t1=['hello',10]/OK

t1=[10,'hello']/Error

当访问一个已知索引的元素,会得到正确的类型:

console.log(t1[0].substring(1))/OK

console.log(tl[l].substring(l))/Error,number^^±'substring

枚举

enum类型是对JavaScript标准数据类型的一个补充。使用枚举类型可以为一组数值赋予友好的名字。

enumColor{

Red

Green.

Blue

)

故举效值默认从。开始依次递熠

,根据特定的名称得到对应的枚举数值

letmyColorColor=ColorGreen/0

console.logmyColorColorRedColorBlue

默认情况下,从0开始为元素编号,你也可以手动的指定成员的数值。例如,我们将上面的例子改成从1开始编号:

enumColorRed=1GreenBlue}

letcColor=ColorGreen

或者,全部都采用手动赋值:

enumColorRed=1Green=2Blue=4}

letcColor=ColorGreen

枚举类型提供的一个便利是你可以由枚举的值得到它的名字。例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们

可以查找相应的名字:

enumColorRed=1GreenBlue;

letcolorName:string=Color2|

console.log(colorName)/'Green'

any

有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型.这些隹可能来自于动态的内容,比如来自用户输入或第三方代

码库。这种情况下,我们不希望类型检查器对这些值进行检瓷而是直接让它们通过编译阶段的检查。那么我们可以使用any类型来标记这

些变量:

letnotSureany=4

notSure='maybeastring'

notSure=false/也可以是个boolean

在对现有代码进行改写的时候,any类型是十分自用的,它允出尔在编译时可选择地包含或移除类型检直。井且当你只知道一部分数据的

类型时,any类型也是有用的。比如,你有一个数组,它包含了不同的类型的

letlistanyO=[1,true,'free']

list[1]=1OO

void

某种程^上来说,void类型像是与any类型相反,它表示没有任何类型.当一个函数没有返回值时,你通常会见到其返回值类型是void

「痂■没有任何类型,一雌来说明,勺返回值不能是undefined和null之夕版值*/

functionfn(i:void{

console.log('fn()')

/returnundefined

/returnnull

/return1/error

)

声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null:

letunusable:void=undefined

object

object表示非原始类型,也就是除number,string,boolean之夕曲类型。

使用object类型,就可以更好的表示像Object.create这样的API.例如:

functionfn2(objobject):object

console.log('fn20'.obji

return{}

/returnundefined

/returnnull

)

console.log(fn2(newStringabc')))

/console.log(fn2('abc')/error

console.log(tn2String))

联合类型

联合类型(UnionTypes)表示取值可以为多种类型中的一种

需求1:定义一个一个函数得到一个数字或字符串值的字符串形式值

functiontoString2(x:number|string):string{

returnxtoString()

)

需求2:定义一个一个函数得到一个数字或字符串值的长度

functiongetLength(x:number)string){

/returnx.length/error

if(xlength){/error

returnxlength

}else{

returnx.toString()length

}

}

类型断言

通过类型断言这种方式可以告诉编译器,"相信我,我知道自己在干什么”.类型断言好比其它语言里的类型转换,但是不进行特殊的

数据检量懈构。它没有运行时的影响,只是在编译阶段起作用。Typescript会假设你,程序员,已经进行了必须的检查。

类型断言有两种形式。其一是“尖括号”语法,另一个为as语法

/,

赞雌(TypeAssertion):可以再痔动指定一个值的类型

语.式一:<类型〉值

方式二:道as类型tsx中只能用这种方式

*/

r需求:定L个函数得到-个字符串或者数值数据的长度*/

functionge:Length(x:number|string){

if((<string>x).length{

return(xasstring)length

}else{

returnx.toString(]length

)

}

console.locKaetLenothCabcd'),aetLength(1234))

类型推断

类型推断:TS会在没有明确的指定类型的时候推测出一个类型

有下面2种情况:1.定义变量时赋值了,推断为对应的类型.2.定义变量时没有赋值推断为any类型

「定义变量时赋值了,推断为对应的类型7

letb9=123/number

/b9='abc'/error

「定义变段殳胸值,推断为any类型7

letb10Iany类型

b10=123

b10='abc'

2.2接口

Typescript的核心原则之一是对值所具有的结构进行类型检直.我们使用接口(Interfaces)来定义对象的类型.接口是对象的状态据性)和

行为(方法)的抽象(描述)

接口初探

需求:创建人的对象,需要对人的属性进行一定的约束

id是number类型,必须有,只读的

name是string类型,必须有

age是number类型,必须有

sex是strin联型,可5殳有

下面通过一个简单示例来观察接口是如何工作的:

在Typescript中,我们使用阅y(Interfaces)来定义对象的类型

接口:是对象的状态隔性)和行为6法)的抽象(描述)

接口类型的对象

多了或者少了属性是不允许的

可选属性:?

只读属性:readonly

*/

r

需求:创建乂的对象,需要对人的属性迸行一定的约束

id昌lumber类型,有,只读的

name悬tring类里,必须有

age是number类型,必须有

sex是string类型,可以没有

7

/定义人的汶口

interfaceIPerson[

idnumber

namestring

age:number

sexstring

}

constpersonl:IPerson={

id:1,

name'tom',

age20,

sex:'男•

)

类型检查器会查看对象内部的属性是否与Person接口描述一致,如果不一致就会提示类型错误。

可选属性

接口里的属性不全都是必需的。有些是只在某些条件下存在,或者根本不存在。

interfaceIPerson[

idnumber

namestring

age:number

sex?:string

)

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号.

可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误.

constperson2IPerson={

id1,

name'tom',

age:20,

isex:'男,/可以没有

)

只读属性

一些对象属性只能在对象刚刚创建的时候修改其值.你可以在属性名前用readonly来指定只读属性:

interfaceIPerson[

readonlyid:number

name:string

age:number

sex?:string

}

一旦赋值后再也不能被改变了。

constperson2IPerson={

id:2,

name'tom',

age:20,

isex「男”可以没有

/XXX:12/error没有在接口中定义,不能有

}

person2id=2/error

readonlyvsconst

最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性.做为变量使用的话用const,若做为属性则使

用readonly。

函数类型

接口能够描述JavaScript中对象拥有的各种各样的外形.除了描述带有属性的普通对象外,接口也可以描述函数类型。

为了使用接口表示函数类型,我们需要给接口定义一个调用签名.它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每

个参数都需要名字和类型.

/*

如可以懿函数类型(参数的类型与返回的类型)

7

interfaceSearchFunc{

sourcestring,subStringstring):boolean

}

这样定义后,我们可以像使用其它接口一样使用这个函数类型的接口.下例展示了如何创建一个函数类型的变量,并将一个同类型的函

数赋值给这个变量。

constmySearchSearchFunc=functionsourcestringsubstring):boolean{

returnsourcesearch*sub)>-1

)

console.log(mySearch('abccl','be'))

类类型

类实现接口

与C#或Java里接口的基本作用一样,Typescript也能够用它来明确的强制一个类去符合某种契约。

/*

类类型:实现距

1.一个类可以实现多个妒

2.一个奴可以继承多个接

□7

interfaceAlarm

alertQ:any;

}

interfaceLight{

lightOn():void;

lightOff():void:

}

classCarimplementsAlarm

alert(){

console.log('Caralert');

}

)

一个类可以实现多个接口

classCar2inplementsAlarmLight!

alertO{

console.log('Caralert');

}

lightOn()(

console.logCCarlighton');

}

lightOff(){

console.logCCarlightoff');

}

}

接口继承接口

和类一样,接口也可以相互继承。这让我们能够从一个接口里复制成员到另一个接口里,可以更灵活地将接口分割到可重用的模块里。

interfaceLightableAlarmextendsAlarmLight{

)

2.3类

对于传统的JavaScript程序我们会使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员使用这些语法

就有些棘手,因为他们用的是基于类的维承并且对象是由类构建出来的。从ECMAScript2015,也就是ES6开始,JavaScript程序员

将能够使用基于类的面向对象的方式。使用Typescript,我们允许开发者现在就使用这些特性,并且编译后的JavsScript可以在所有主

流浏览器和平台上运行,而不需要等到下个JavaScript版本。

基本示例

下面看一个使用类的例子:

/,

类的基本定义与使用

*/

classGreeter{

,声明属性

messagestring

i构造方法

constructor(messagestring){

thismessage=message

}

/一般方法

greet():string{

return'Hello'+thismessage

)

}

/创建类的实例

constgreeter=newGreeterworld')

i调用实例的方法

console.logfgreeter.greet())

如果你使用过C#或Java,你会对这种语法非常熟悉。我们声明一个Greeter类。这个类有3个成员:一个叫做message的属性,一

个构造函数和—个greet方法.

你会注意到,我们在引用任何一个类成员的时候都用了this.它表示我们访问的是类的成员.

后面一行,我们使用new构造了Greeter类的一个实例。它会调用之前定义的构造函数,创建一个Greeter类型的新对象,并执行构造

函数初始化它。

最后一行通过greeter对象调用其greet方法

继承

在Typescript里,我们可以使用常用的面向对象模式。基于类的程序设计中一种最基本的模式是允许使用继承来犷展现有的类.

看下面的例子:

/,

类的继承

*/

classAnimal;

run(distancenumber){

console.logfAnimalrun${distancefm)

}

)

classDogextendsAnimal{

cry(){

console.log('wang!wang!')

)

}

constdog=newDog()

dog.cryO

dog/可以调再从父中继承得到的^法

这个例子展示了最基本的继承:类从基类中继承了属性和方法。这里,Dog是一个派生类,它派生自Animal基类,通过extends关

键字.派生类通常被称作子类,基类通常被称作超当

因为Dog继承了Animal的功能,因此我们可以创建一个Dog的实例,它能够cry()和run()0

下面我们来看个更加复杂的例子。

classAnimal{

namestring

cunblruulur(ruiiiie.siring){

=name

}

run{distancenumber=O){

console.log(${thisnamerunS{distancefm)

}

)

classSnakeextendsAnimal

constructor(namestring){

/碉父类型校管方法

supername

)

/重写父类型峭去

run(distancenumber=5){

console.log('sliding...,)

super.run(distance

}

)

classHorseextendsAnimal{

constructor(namestring){

崛父类型构窗法

supername

}

/重写文类型的方法

run(distancenumber=50){

console.k)g('dashing...')

/调用众类型的一般方法

super.run(distance

)

XXX(){

console.log('xxx(),)

}

)

constsnake=newSnake('sn')

snakerun()

consthorse=newHorse['ho')

horserun()

位类型弓隔指向子类型的实例=»多水

consttomAnimal=newHorseho22')

tom.run()

尸如黯■类矍没有扩展的方法,可以让子类型弓用指际类型的实例^

consttom3Snake=newAnimaltom3')

tom3.run()

r如果子类里有扩展的万法,不能il子类型弓周指向爻类型的实砌

/consttorr2:Horse=newAnimal('tom2')

/tom2.run()

这个例子展示了一些上面没有提到的特性。这一次,我们使用extends关键字创建了Animal的两个子类:Horse和Snake。

与前一个例子的不同点是,派生类包含了一个构造函数,它必须调用super。,它会执行基类的构造函数。而且,在构造函数里访问

this的属性之前,我们一定要调用superO0这个是TypeScript强制执行的一条重要规则。

这个例子演示了如何在子类里可以重写父类的方法。Snake类和Horse类都创建了run方法,它们重写了从Animal继承来的run方法,

使得run方法根据不同的类而具有不同的功能。注意,即使tom被声明为Animal类型,但因为它的值是Horse,调用tom.run(34)时,

它会调用Horse里重写的方法。

sliding...

snrun5m

dashing...

horun50m

公共,私有与受保护的修饰符

默认为public

在上面的例子里,我们可以自由的访问程序里定义的成员。如果你对其它语言中的类比较了解,就会注意到我们在之前的代码里并没有

使用public来做修饰;例如,C#要求必须明确地使用public指定成员是可见的.在Typescript里,成员都默认为public.

你也可以明确的将一个成员标记成public,我们可以用下面的方式来重写上面的Animal类:

理解private

当成员被标记成private时,它就不能在声明之的类的外部访问。

理解protected

protected修饰符与private修饰符的行为很相似,但有一点不同,protected成员在派生类中仍然可以访问.例如:

/,

访问修饰符用来描述类内部的属性亦法的可访问性

public:默认值公开的外部也可以访问

private:兵能类内部可以访问

protected:类内部f吁类可以访问

*/

classAnimal{

publicnamestring

publicconstructornamestring){

=name

}

publicrun(distancenumber=0){

console.loa(S{thisnamerunS{distance}m)

}

}

classPersonextendsAnimal{

privateage:number=18

protectedsexstring='男'

run(distancenumber=5){

console.log('Personjumping...,)

super.run(distance

}

)

classStudentextendsPerson{

run(distancenumber=6){

console.log('Studentjumping...,)

console.log(thissex)仔类能看到皮类中受保护的成员

/console.log(this.age)/子类看不到‘爻类中私有的成员

super.run(distance

}

}

console.Iog(newPerson('abc').name)/公开的可见

/console.logfnewPerson('abc').sex)I受保护的不可见

/console.Iog(newPerson('abc').age)/私有的不可见

readonly修饰符

你可以使用readonly关键字将属性设置为只读的.只读属性必须在声明时或构造函数里被初始化。

classPerson;

readonlynamestring='abc'

constructorsnamestring){

=name

}

)

letjohn=newPerson'John')

/='peter'/error

参数属性

在上面的例子中,我们必须在Person类里定义一个只读成员name和一个参数为name的构造函数,并且立刻将name的值赋给

,这种情况经常会遇到。参数属性可以方便地让我们在一个地方定义并初始化一个成员。下面的例子是对之前Person类的修

改版,使用了参数属性:

classPerson2

constructorreadonlynamestring){

}

constp=newPerson2jack')

console.log:pname

注意看我们是如何舍弃参数name,仅在构造函数里使用readonlyname:string参数来创建和初始化name成员。我|门把声明和赋值合并

至一处。

参数属性通过给构造函数参数前面添加一个访问限定符来声明。使用private限定一个参数属性会声明并初始化一个私有成员;对于

public和protected来说也是一样。

存取器

Typescript支持通过getters/setters来截取对对象成员的访问.它能帮助你有效的控制对对象成员的访问.

下面来看如何把一个简单的类改写成使用get和set8首先,我们从一个没有使用存取器的例子开始。

classPerson;

firstName:string="A'

lastName:string='B'

getfullName(){

returnthisfirstName++this.lastName

)

setfullName(value){

constnames二valuesplit('-')

thisfirstNamenames!0]

this.lastName=names[1]

}

}

constp=newPerson)

console.logfpfullName

pfirstName='C'

plastName='D'

console.logfpfullName

pfullName='E-F'

console.log;pfirstNameplastName)

静态属性

到目前为止,我们只讨论了类的实例成员,那些仅当类被实例化的时候才会被初始化的属性。我们也可以创建类的静态成员,这些属性存

在于类本身上面而不是类的实例上。在这个例子里,我们使用static定义origin,因为它是所有网格都会用到的属性。每个实例想要访

问这个属性的时候,都要在origin前面加上类名。如同在实例属性上使用this.xxx来访问属性一样,这里我们使用Grid.xxx来访问静态

属性。

/*

静态属性,是类对象的属性

关静态属性.是类的实例对象的属性

7

classPerson;

namel:sting='A'

staticnan^2string='B"

}

console.logPersonname2)

console.log(newPersonnamel)

抽象类做为其它派生类的基类使用.它们不能被实例化。不同于接口,抽象类可以包含成员的实现细节,abstract关键字是用于定义抽象

类和在抽象类内部定义抽象方法。

‘抽象类

不能创建实只有实现类才能创建实例

可以包含未实现的抽象方法

*/

abstractclassAnimal:

abstractcry()

run(){

console.tog('runO,)

)

}

classDogextendsAnimal{

cry(){

console.logCDogcry(),)

)

}

constdog=newDogi

dogcry()

dogrun()

2.4函数

函数是JavaScript应用程序的基5出,它帮助你实现抽象层,模拟类,信息隐藏和噗块。在TypeScript里,虽然已经支持类,命名空间

和模块,但函数仍然是主要的定义行为的地方.Typescript为JavaScript函数添加了额外的功能,让我们可以更容易地使用.

基本示例

和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。你可以随意选择适合应用程序的方式,不论是定义一系列API

函数还是只使用一次的函数。

通过下面的例子可以迅速回想起这两种JavaSzript中的函数:

,命名函数

functionadd(x.y){

returnx+y

)

/匿名函数

letmyAdd=function(xy){

returnx+y:

)

函数类型

为函数定义类型

让我们为上面那个函数添加类型:

functionadd(x:numbery:number):number{

returnx+y

}

letmyAdd=function(x:number,y:number):number{

returnx+y

)

我们可以给每个参数添加类型之后再为函数本身添加返回值类型.TypeScript能够根据返回语句自动推断出返回值类型.

书写完整函数类型

现在我们已经为函数指定了类型,下面让我们写出函数的完整类型。

letmyAdd2(xnumbery:number)=>number=

function(xnumber.ynumber):number{

returnx+y

)

可选参数和默认参数

Typescript里的每个函数参数都是必须的。这不是指不能传递null或undefined作为参数,而是说编译器检查用户是否为每个参数都传

入了值。编译器还会假设只有这些参数会被传递进函数.简短地说,传递给一个函数的参数个数必须与函数期望的参数个数一致.

JavaScript里,每个参数都是可选的,可传可不传。没传参的时候,它的值就是undefined。在TypeScript里我们可以在参数名旁使

用?实现可选参数的功能。比如,我们想让lastName是可选的:

在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。它们叫做有默认初始化值

的皴。让我们修改上例,把firstName的默认值设置为“A”。

functionbuildNameifirstName:strings'A',lastName?:string):string{

if(lastName।{

returnfirstName++lastName

}else{

returnfirstName

}

}

console.logthuildNameCC,'D'))

console.lo^buildNameCC'))

console.log(buildName())

剩余参数

必要参数,默认参数和可选参数有个共同点:W们表示某一个参数.有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进

来。在JavaScript里,你可以使用arguments来访问所有传入的参数。

在TypeScript里,你可以把所有参数收集到一个变量里:

剩余参数会被当做个数不限的可选参数。可以一个都没有,同样也可以有任意个。编译器创建参数数组,名字是你在省略号(…)后面

给定的名字,你可以在函数体内使用这个数组,

functioninfo(x:string,argsstringO){

console.log(xargs)

)

infofabcW.V/a')

函数重载

函数重载:函数名相同,而形参不同的多个函数

在JS中,由于弱类型的特点和形参与实参可以不匹配,是没有函数重载这一说的

但在TS中,与其它面向对象的语言(如Java)就存在此语法

/,

函数名相同,而形参不同的多个函数

就我们有一个add函数,它可以接收"、tring类型的第面拼接,也可以接收坊number类型的例面相加

7

/重载函数声明

functionadd(x:string,y:string):string

functionadd(xnumbery:number):number

1定义函数实现

functionadd(x:string|number,y:string|number):string|number{

/酶现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个x+y

if(typeofx==="string'&&typeofy==="string'){

returnx-y

}elseif(typeofx==='number'&&typeofy==='number'){

returnx-y

}

}

console.log(add(1.2))

console.log[add('a',"b'))

/console.log(add(1,'a"))/error

2.5泛型

指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。

引入

下面创建一个函数,实现功能:根据指定的数量count和数据value,创建一个包含count个value的数组

不用泛型的话,这个函数可能是下面这样:

functioncreateArray(value:any,countnumber):aryQ{

constarr:any[]=[]

for(letindex=0;index<countindex++){

arrpushvalue

}

returnarr

)

constarr1=createArray(11,3)

constarr2=createArray('aa",3)

console.logarrl0].toFixed()arr2[0].split("))

使用函数泛型

functioncreateArray2<T>ivalueTcountnumber){

constarr:Array<T>=0

for(letindex=0;index<countindex++){

arr.pushvalue

}

returnarr

}

constarr3-createArray2<number>(11.3)

console.log(arr3[;0].toFixed())

/console.log(arr3[0].split("))/error

constarr4createArray2<string>('aa',3)

console.log(arr4[0].split("))

/console.log(arr4[0].toFlxed())/error

多个泛型参数的函数

functionswap:K,V>(a:K.bV):[K.V]{

returnab]

)

c51slresullswup<slri“g,nuinbtsr^'ubv',123)

console.log(result[0].length.result[1].toFlxed())

泛型接口

在定义接口时,为接口中的属性或方法定义泛型类型

在使用接口时,再指定具体的泛型类型

interfaceIbaseCRUD<T>{

dataTO

add:(t:T)=>void

getByld(idnumber)T

)

classUser|

id?:number;//d壬奢

namestring;/姓名

age:number;1年龄

constructorinameagei{

this.name=name

this.age=age

}

}

classUserCRUDimpleme

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论