==心得:对前端开发者来说,TS能强化了「面向接口编程」这一理念。我们知道稍微复杂一点的程序都离不开不同模块间的配合,不同模块的功能理应是更为清晰的,TS能帮我们梳理清不同的接口。,TS能让我更自信的写前端代码,这种自信来自 TS的类型检测可以帮我们避免很多可能由于自己的忽略造成的 bug==
一、基本数据类型
1、布尔类型:
let flag:boolean = false
flag = true
2、数字类型
let num:number
num = 10
3、字符串类型
let str:string
str = 'this is strType'
4、数组类型
let arr:any[] = []//any类型指任何类型,数组里面既可以放数字类型也可以放字符串
let arrNum:number[]//只能在数组里面存放数字类型
let arrString:string[]//只能在数字里面存放字符串类型
其他方式定义数组
let arrNum:Array<number> = [1,3,5]
let arrStr:Array<string> = ['a','b','c']
5、元组类型
let arr:[string,number,boolean] = ['str',100,true]
6、枚举类型
enum 枚举名{
标识符[=整型常数]
标识符[=整型常数]
标识符[=整型常数]
...
}
定义一个flag枚举类型,1表示成功,-1表示失败
`enum Flag{
success = 1
error = -1
}`
let f:Flag = Flag.success
7、任意类型
let anyType:any
指定为空类型
let number : null | number
void类型,一般用于方法,表示没有返回任何类型
function funVoid():void{
console.log('没有返回值')
}//void返回类型
function funNumber():number{
return 100
}//定义返回number
二、函数的定义
1、函数声明法
function fun1():string{
console.log('no return')
}
function fun2():number{
return 100
}
function fun3():string{
return 'string'
}
2、匿名函数
const fun1 = function():void{
console.log('no return')
}
const fun2 = function():number{
return 100
}
const fun3 = function():string{
return 'string'
}
3、typescript定义方法传参
const getInfo = function(name:string,age:number):string{
return `${name}---${age}`
}
箭头函数
const getInfo = function(name:string,age:number):string=>{
return `${name}---${age}`
}
可选参数:在变量后加一个?,表示这个参数可传可不传
const getInfo = function(name:sting,age?:number):void=>{
}
默认参数
const getInfo = function(name:string,age:number=18):void=>{
}
剩余参数
const surplus = (a:number,b:number,c?:number):number=>{
return a+b+c
}
surplus(1,2) //输出3
定义一个数组来接收参数
const sum = (...res:number[])=>{
let sum = 0
res.map(item =>{
sum +=item
})
return sum
}
sum(1,2,3) //打印处和为6
三、typescript中的类和继承
1、类的定义
class Person{
name:string //属性
//构造器,实例化类的时候会触发的方法
constructor(name:string){
this.name = name
}
//定义一个set和get的方法
getName():string{
return this.name
}
setName(name:string):void{
this.name = name
}
//定义一个人物动作的方法
run():string{
return `${this.name}在跑步`
}
}
<!--实例化一个人类-->
const p = new Person('张三')//传入张三,因为定义了构造器,所以这里必传
p.run()//打印出张三在跑步
p.setName('李四')//调用setname方法,传入李四
p.run()打印出李四在运动
2、类的继承 extends和super
<!--定义一个中国人继承上面的人类-->
class ChineseMan extends Person{
constructor(name:string){
super(name)
}
work():string{
return `${this.name}在工作`
}
}
const cm = new ChineseMan('王五')
cm.work()//打印王五在工作
cm.run()//打印王五在跑步
3、类的修饰符 public:在子类,类内部和外部都可以调用 private:只能在类内部调用 protected:不能在类外部调用*
<!--定义一个动物类-->
class Animal{
public name:string
public age:number = 20
//静态属性
public static color:string = '黑色'
//构造器
constructor(name:string){
this.name = name
}
//静态方法
static run(name:string){
console.log(this.color)//这里可以获取到值,因为定义的是一个静态属性
console.log(this.age)//反之这里拿不到age的值,因为静态方法不能直接调用类里面已声明值的属性
return `${name}在跑步`
}
}
<!--调用静态方法-->
Animal.run('李四')//打印处李四在跑步
4、多态 父类定义一个方法不去实现,让继承他的子类去实现,每一个子类有不同的表现
//定义一个动物类
class Animal{
public name:string
constructor(name:string){
this.name = name
}
//定义一个吃的方法
eat():void{
}
}
//定义一个小狗去继承动物类
class Dog extends Animal{
constructor(name:string){
super(name)
}
eat(){
return `${this.name}吃骨头`
}
}
//定义一个小猫去继承动物类
class Cat extends Animal{
constructor(name:string){
super(name)
}
eat(){
return `${this.name}吃鱼干`
}
}
实例化类
const dog = new Dog('小狗')
dog.eat()//小狗吃骨头
const cat = new Cat('小猫')
cat.eat()//小猫吃鱼干
5、抽象类 1、提供其他类继承的基础,不能被直接实例化 2、用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现 3、抽象方法只能放在抽象类中
//定义一个抽象类
abstract class Animal{
publi name:string
constructor(name:string){
this.name = name
}
//定义一个抽象方法,子类必须实现
abstract eat():any
//普通方法,子类可以不用实现
run():any
}
const animal = new Animal()//会报错,因为无法创建抽象类的实例
<!--定义一个小狗类去继承animal-->
class Dog extends Animal{
constructor(name:string){
super(name)
}
//实现父类的抽象方法(必须实现,不然会报错)
eat(){
return `${this.name}吃骨头`
}
run(){
return `${this.name}跑步,在子类可以不定义`
}
}
const dog = new Dog('狗子')
dog.eat()//狗子在吃骨头
dog.run()//狗子在跑步,在子类可以不定义
四、typescript的接口
接口的作用,在面向对象编程中,接口是一种规范定义,他定义了行为和动作的规范,起到了一种限制和规范。 接口定义了某一批类所需要遵守的规范,接口不必关心这些类的内部状态数据,也不关心类里面实现的细节,只规定了这批类里必须提供某些方法,提供这些方法可以满足实际需要。
//定义一个接口
interface FullName{
firstName:string
secondName:string
}
//方法实现接口
function fullName(name:FullName):string{
return `${name.firstName}----${name.secondName}`
}
const data = {
otherParams:9//可以添加其他参数
firstName:'张'
secondName:'三'
}
fullName(data) //张-----三
1、封装一个ajax接口
$ajax({
type:'get',
url:'https://baidu.com',
data:{username:$("#username").val(),content:$("#content").val()},
datatype:'json'
})
//定义一个接口
interface ajax{
type:string,
url:string,
data:any,
datatype:string
}
//定义一个方法继承接口
function ajax(config:ajax):any{
const xhr = new XMLHttpRequest
xhr.open(config.type,config.url,true)
xhr.send(config.data)
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// console.log('请求成功')
if (config.datatype == 'json') {
// console.log(JSON.parse(xhr.responseText))
}
}
}
}
//调用方法
const data = {
type:'get',
url:'baicu.com',
data:'name=zhangsan',
datatype:'json'
}
ajax(data)
2、函数型接口 对方法传入的参数以及返回值进行约束
//定义一个加密型函数接口
interface encrapt{
//约束以下这个函数
(key:number,value:number):number
}
//实现这个函数接口
const md5:encrapt = function (key:number,value:number):number{
return key+value
}
const sha1:encrapt = function (key:number,value:number):number{
return key+value
}
//调用
sha1(10,20) //30
md5(20,30) //50
3、类类型接口 对类的约束,和抽象类有点相似
//定义动物类接口
interface Animal{
name:string,
eat(str:string):void
}
//实现接口
class DogImp implements Animal{
name:string
constructor(name: string) {
this.name = name
}
eat():void{
console.log(`${this.name}在吃东西`)
}
}
//实例化类
const di = new DogImp('小狗')
di.eat()//小狗在吃东西
class CatImp implements Animal{
name:string
constructor(name: string) {
this.name = name
}
eat(str:string):void{
console.log(`${this.name}在${str}`)
}
}
const ci = new CatImp('小猫')
ci.eat('吃鱼干')//小猫在吃鱼干
4、接口的拓展:接口可以继承接口
//动物类接口
interface Animal{
eat():void
}
//人类接口 继承动物类接口
interface Person implements Animal{
name:string
constructor(name:string){
this.name = name
}
//工作方法
work():void{
console.log(`${this.name}在工作`)
}
//吃的方法
eat():void{
console.log(`${this.name}在吃饭`)
}
}
//实例化类
const person = new person('张三')
person.work()//张三在工作
person.eat()//张三在吃饭
四、typescript中的泛型
解决类,接口方法的复用性,以及不特定数据的支持性
现有个方法需要同时返回number和string类型
写法一:写两个方法,造成了代码的冗余
function fun1(num:number):number{
return num
}
function fun2(str:string):string{
return str
}
写法2:定义any类型,但是放弃了类型检查,比如传入number类型,就比如返回number类型,传入string类型就必须返回string类型
function fun(str:any):any{
return str
}
写法3:泛型,T表示具体什么类型,是由调用这个方法的时候决定的
function fun<T>(str:T):T{
return T
}
//调用
fun<number>(100)//这里定义了number类型,就只能传入number
fun<string>('str')//这里定义了字符串类型,就只能传入字符串
2、泛型类
求最小值
class MinNum{
public list:number[]
addd(num:number):void{
this.list.push(num)
}
min():number{
let min = this.list[0]
this.list.map(item =>{
if(item < min){
min = item
}
})
return item
}
}
const mn = new MinNum()
mn.add(1)
mn.add(2)
mn.min()//输出1
用泛型,定义一个泛型类
class MinNum<T>{
publi list:T[]
add(num:T):void{
this.list.push(num)
}
min():T{
let min = this.list[0]
this.list.map(item =>{
if(item < min){
min = item
}
})
return min
}
}
const mn = new MinNum<number>()//实例化类,并定义类型
mn.add(1)
mn.add(2)
mn.min()//输出1
3、泛型接口 普通接口
interface configFun{
(val1:string,val2:string):string
}
const interFun:configFun = function(val1:string,val2:string){
return val1+val2
}
interFun('晚上','吃饭')
泛型接口
interface configFun<T>{
(val:T):T
}
const interFun :configFun<T>(val:T):T{
return val
}
interFun<string>('嘻嘻哈哈')
interFun<number>(100)