TS 个人总结

173 阅读5分钟

TS 个人总结

ts 陆陆续续也做了几个项目,最近试着在结合项目做一些总结,为自己做个系统的总结
tsjs 的超集,按照数学理解, 即jsts 的真子集

类型

原始类型

1. String,Boolean,Number

  1. 定义 都可以分为显示定义和隐式定义(一般使用 隐式定义)
    以 string 举例:
  • 隐式定义
// 隐式定义 ts 通过自己的类型推论,得出变量 a 为 string 类型
let a = "b"
a = 12 // Error 
  • 显式定义
let b:string = "c"
let b:boolean = false
let b:number = 1 
  • 使用 type 定义
type S  = string
let c:S = "d"
  • 使用构造函数定义
let a:String = new String("b")
let a:string = String("b")

建议不要使用 String 定义

3.string 有模板字面量,和 js 一样

    let myName ="tsk"
    let s: string = `Hello, my name is ${myName}.

复杂类型

Function

函数部分比较多,比较常用的类型

1. 定义

1. 内联定义
// 函数声明
function add (a:string,b:number):string {
    console.log(a,b)
}
//  函数字面量
const add:(a:string,b:number)=>string = (a,b)=>{
}
2. 类型别名定义
type Add = (a:string,b:number)=>string
const add:Add = (a,b)=>{
    return a
}
// 函数传参的时候需要和 Add 的类型保持一致
add("a",1)
3. 接口定义
interface IAdd  {
 (a:string,b:number):string
}
const add:IAdd = (a,b)=>{
 return a
}
add("a",1)

2. 形参

  1. 参数默认值
 function Add(a:string,b:number=12){
     
 }
// Add("a",1) // 如果 传值的话,第二个参数只能是 数值类型
 Add("a") 可以缺少第二个参数
  1. 可选参数
 // 有一些参数是不是必填项
 function Add(a:string,b?:number){
   
  }
  Add("a")
  // Add("a",12) 如果要传入第二个参数,只能是 number 类型
  1. 剩余参数
// 第二个参数是剩余参数,而且必须是最后一个参数
function add(a:string,...rest:string[]){
    
}
add("a","b","c") // 后面的参数是必须都是字符串,可以使用 any[]
  1. 函数重载
function add(a:string):string;
function add(a:number):number;
// 需要实现重载,参数是包含他们所有类型的联合类型
function add(a:string| number):string | number{
    return "a"
   // return 12
}

实际例子

 interface User {
     name: string;
     age: number;
}
function test(para: User): number;

function test(para: number, flag: boolean): number;

function test(para:User | number,flag?:boolean):number{
    // 类型收紧
    if(typeof para == "number"){
      return 12
    }else {
      return para.age
    }
}
const user = {
 name: 'Jack',
 age: 666
};
const res = test(user); // 这个地方只能用 user 类型或者使用 (12,false)
//相当于固定了传入的类型,在函数体内进行分发
  1. 使用 this this 本身在js中不好判断,ts 更难了
    所以有些时候显示指定
    this 需要在函数形参的第一项,不占位,打包过后自动去除
const button = document.querySelector("button");
button?.addEventListener("click", handleClick);

function handleClick() {
 console.log("Clicked!");
 // 'this' implicitly has type 'any' because it does not have a type annotation(注解).
 // this 现在是 any 类型
 this.removeEventListener("click", handleClick);
}
// 绑定 this
function handleClick(this: HTMLElement) {
 console.log("Clicked!");
 // 'this' implicitly has type 'any' because it does not have a type annotation(注解).
 // this 现在是 确定的 HTML 类型
 this.removeEventListener("click", handleClick);
}

Object ( Array & Object )

Array

1. 定义
  1. 默认定义推论
    // 如果像这样定义了 数组中只有一种类型,ts 会自动推论成 number[]
    let arr = [1,2,3]
    arr.push("23") // error 因为是 number[]
  1. 普通定义
// 定义单一类型 string 可以替换成 boolean ,number,{ name:'xx',age:12}
let arr:string[] =[1,2,3]
// 定义多种类型 
let arr:(string|number)[] = [1,2,3,6] // 就可以使用 string 和 number 类型的数组
  1. Array 定义
    // 同理可以替换
    let arr:Array<number> = [1,2,3,6]
    let arr:Array<string|number> = [1,2,3,6,'a']
  1. 使用 索引 定义
type D = {
 [k:number]:number
}
let arr:D = [1,2,3,6]
  1. 只读数组
 let arr: ReadonlyArray<number|string> = [1,2,3,"a"];
 arr.push(1) //error 不允许添加新的属性
 arr[0] = 12;
 arr.push(5); 
 arr.length = 100;
 //right
ro.slice(1,1)
ro = ro.concat(12)
ro = ro.map(item=>{
    return item
})

Object

1. 定义
  1. 普通定义
interface IObj  {
    name:string,
    age:20 //一个固定值
}
let o:IObj = {name:'zs',age:20 }
  1. 索引定义( 可以设置任意字段 )
 interface IObj  {
     [key:string]:string,
     age:number
 }

Object其他特点

定义只读属性
interface IObj {
  readonly  name:string,
    age:20
}
let o:Obj = { name:'zs',age:20}
o.name = "liis" // error ,因为是只读属性
可选属性
 interface IObj {
    name:string,
    age:20,
    sex?:boolean
}
let o:IObj = {name:'zs',age:20 } //sex 可以不传,传递的话需要 布尔

class

类 是具有相同属性和方法的 集合
ts 中的类 不仅具有 js 类的所有功能,还有一些额外的功能

//readonly 只读
// Static 静态方法
//Point.static
// public 公有的,完全开放,实例化对象只能调用public 定义的内容;
// private 私有的,私有属性在其他类中无法调用,私有方法是不被继承的,也不能override; 只有自己可以使用
// protected 受保护的,protected定义的变量只能在类和其子类中调用(可以被继承),通过this调用,但是在实例化的对象中是不可以调用;
// let p1 = new Person() 自己和自己的孩子内部使用
// p1.getName() 不可以,必须使用 super.getName()

class Point{
protected name: string;
protected age:number;
// constructor(public arg1: T, public arg2: U) {} 一步到位不用定义属性,使用了参数的默认属性
   constructor(name:string,age:number){
       this.name = name;
       this.age = age
   }
   public getMyname(){
       return this.name
   }
   private getMyage(){
       return this.age
   } 
   protected getMyinfo (){
       this.getMyage()
       return this.name+this.age
   }
}

let p1 = new Point("xa",12)
// 无法获取 p1.getMyinfo 智能在自己内部使用 或者自己孩子使用

class P2 extends Point{
   constructor(name:string,age:number){
       super(name,age)
   }
   getMyinfo2 (){
       super.getMyinfo()
   }  
}
let p3 = new P2('zs',12)
console.log(p3.getMyname())
console.log(p3.getMyname)

note:先暂时写到这,以后想到了再补充 time 2022.5.17 9:55

ts 内置方法

内容较多,放在下一个章节