TypeScript的基本使用

68 阅读7分钟

划重点

Type并不是创建一个新的类型,,而interface会尽可能使用interface如果不想用接口暴露很多信息,并且想用联合类型或者数组类型,通常使用Type


export default class Parent extends Vue { 
// 声明数据 
private readonly name = SakuraSnow;
private readonly age = 19; 
}

readonly -只读

private -私有 public -公用属性

protected -被保护的。针对 对象。因为一个类可以化身为好多好多的dui对象。对于一些这些dui'对象应该共有的一样的属性不应该让对象有访问和修改的权力。

  • 加上private和readonly后,这个属性就变成了私有属性,外部访问会报错,同时是只读的,想要修改它的值也会报错。(这里的报错均是指静态类型检查报错,要访问实际上还是可以访问的,要修改实际上也是可以修改的)

js的基本类型

简单类型

null undefined string number bool synobol

类型声明 ts支持的js类型


const a:undefined=undefind

const b:null=null

const c:string='hi'

const d:booleab=ture

const e:symbol=Symbol('hi')

const f:bigint=123n

const obj:Object={}

const arr:Array<string|number|null>=['1','2','3',4,null]

函数声明的几种方式


//接收的是number ,返回的是number  //这是第一种写法
const add=(a:number,b:number):number=>{
    return a+b
}

    //第二种写法  //函数体后面才开始,前面只是声明类型
    
    const add:(a:number,b:number)=>number=>(a,b)=>a+b

    //最终用法
    
    type Add=(a:number,b:number)=>number
    
    const add2:Add=(a,b)=>a+b

    //js的函数也是一个对象

    interface AddWinProps{
        (a:number,b:number):number
        xxx:string
    }
    
    const add2:AddWinProps=(a,b)=>a+b
    add2.xxx='hi yyy'

ts比js多的额外的类型


    let a:any='hi'  //任何类型,可以随意改变
    
    let b:unknown= JSON.parse('{'name':'frank'}') //any 是没有任何限制,unknown也是任何限制,但是用之前你得明确它是一个什么类型。 需要用到断言。
    
    //我不知道b是什么,但是我猜b是什么,因为数据是网络上来的,我不能确定他一定是name:frank,
    
    
   //unknown 要用的话,首先要明确它是一个什么样的类型
   //现在不知道它的类型,但是我会在某个时候明确它的类型的

断言


type B={name:string}
type E={age:string}

let b:unknown=JSON.parse('{'name':'hhhhhh'}')

console.log((b  as B).name) //断言

console.log((b  as E).age)


    let print:()=>void=function(){   //void 没有返回值
            console.log(1)
    }

    print()

never

  • 如果代码中让一个东西变成了 never ,说明你的代码出错了

    type Dir=1|2|3|4|undefined
    
    let dir:Dir
    
    switch(dir){
        case 1:
             break;
        case 2:
            break;
        case 3:
             break;
        case 4:
            break;
        case undefined:
            break;
        default:
            console.log(dir)
            break;  
    }

    //出现的结果就是 打印的 never ,但是default以下的代码就是不可能运行的,
    //因为它只有五种取值,把五种取值都覆盖到了---那就是never ,
    
    // 理解: 就是一直集合的形式。
    
    //假设 Dir 是一个集合,它有五个元素,在判断循环体里面把这五个值都抛去了,那么请问最后这个集合还剩下什么??
   // 还剩下空集合。
   // 所以never 表示空集 ,它既不是any也不是unknown ,也不是void,就是什么也没有。。
   //也不是空,因为空也是一个值
    
   //所以 never 表示的就是:
   
   // 不应该存在的,或者说就是没有这个类型 。。
    
   // 我们没有使用这个nevertf ,但是推出了一个never 。。 


    type x=number & string  //& 和的意思 ,取两个集合中相交的结果
    
  • Y 的类型就是他们相交的:2|3

    • 那么字符串和数字能相交吗,不能相交,所以他们两个的集合的交集为空!
    • 那空集就是never表示,所以x的类型就是never

元组


    let p:[number,number] =[100,200]
    
   let p2:[number,string,boolean]=[100,'x',trun]
    
    //这就是元组,元组的长度可以随便,但是赋值的时候必须长度一样,而且要符合这个类型
    
   // 元组只是ts的概念,js里面不存在元组,

枚举


    //默认情况下,从0开始为元素编号
    
    enum Dir2{东,南,西,北}
    
    let d:Dir2=Dir2.东  // 实际等于 0
    
    let d2:Dir2=Dir2.西
    
    console.log(d)   //枚举一般不这样用,很麻烦  // 不直观,而已还是数字而不是字符串,还打了个点
    
    //这种能不使用就不使用,除非后端要用到。。
 

  //推荐用法
    
    type Dir='东'|'南'|'西'|'北'
    
    let dir:Dir='东'   //这就是枚举, 枚举就是把01234 ,变成对应的一个标志。
    


TypeScript 泛型的基本定义和使用

什么是泛型?

1. js函数


var fn =(x:number)=>x+1

那么能不能在ts里面也支持这个函数呢

2.你得给我一个类型,我才知道是什么

比如你得给我一个类型T,给你给你返回T或者T的数组

type F<T> = T | T[]

var fn =(x:number)=>x+1

重点:就是这个F是一个类型,但是这个类型它是一个函数,就是我这个类型必须在接受一个类型

参数写在<>括号里面,然后参数的名字叫做T

比如说你传给我一个number:

注意: 永远都是类型


type F<T> =T|T[]

type FNumber=F<number>

type FString=F<string>

var fn =(x:number)=>x+1

就是类型也支持像函数一样的参数。

泛型有什么用呢?为什么需要这个东西?

泛型=广泛的类型

跟具体的类型或者说比较窄的类型相对应


const add=(a:number.b:number)=>a+b

const add=(c:string,d:string)=>c+b

那么在函数里面怎么去写这个类型呢??

接受一个a和一个b,然后返回一个东西,这个东西是什么不知道,

先接受一个类型参数叫做 ,

如果给的这个 T 是number 那么这个a就是number,

如果给的这个 T 是string 那么这个a就是string,


type add<T>=(a:T,b:T)=>T

返回的这个类型跟T 是一样的


type Add<T>=(a:T,b:T)=>T

type AddNumber=Add<number>

它的类型a是number,b是number,返回number


type Add<T>=(a:T,b:T)=>T

const addN:Add<number>

直接写它的类型是什么

Add 这就是一个具体的类型

我传这个number进去之后,它就不是一个泛型了,而是一个具体的类型

在传之前它是一个泛型,在传之后它是一个具体的


type Add<T>=(a:T,b:T)=>T

const addN:Add<number>=(a,b)=>a+b

const addS:Add<string>=(a,b)=>a+''+b

这时候就不用写ab的类型了。

可以认为是:

泛型的调用或者泛型的收展

这个 可以传更复杂的,可以传任何类型

到这就是讲到了泛型的最基本的定义和使用


ts重载

重载是什么呢??重载解决的需求又是什么呢?

很多时候我们用泛型就能解决,但是又为什么要用到重载呢?

泛型最终还是得给出一个具体的类型,

image

最后会发现泛型不够用,泛型最终会变成一个类型。

<number | string> 这个 | 其实就是一个联合类型

泛型满足不了的需求就是a是什么类型然后b就一定是什么类型,这个是做不到的

而且同时要支持number和string。

重载的意思是什么?

重载:可以认为是支持多种签名

image

直接写函数名字写三次,然后每次写不同的类型就好了。。

image

最后一个add2的any其实是随便写的,写啥都可以,一般是写any。。

image

这样就通过重载来保证,我一个一个的告诉你,每一种类型返回什么样的东西,
而不是像泛型那样,比较宽泛的去说这个类型

可选参数的重载

image

优化

image

重载的话一般是为了让一个函数,满足多重的参数条件。

在第三个get以上的是每一种的实现, 最后一个的get是把每一种的实现给加起来。 然后在里面去做if else 判断。。

常见的是用两种来判断, 1.用typeOf来判断

  1. 用参数的长度来判断 arguments
这些就是重载常见的两种形式

image

加上?号就是为可选。