TS的基本类型

144 阅读7分钟

变量声明

// for(var i:number=0;i<10;i++){
//     setTimeout(function(i:number){
//         console.log(i);
//     },0,i)
// }

接口

对象接口

  • 基本格式
var obj:{a:number,b:number}={a:1,b:2};
  • 修改值
obj.a=10;
obj.b=30;
  • 添加属性
// c就是缺省属性
var obj:{a:number,b:number,c?:number}={a:1,b:2};
obj.c=40;
  • 删除属性:只能删除缺省属性。a,b是必要属性,无法删除
delete obj.c;
​
  • 对象任意添加属性:[key:string]:number key就是属性名变量,string是属性名的类型,:number值的类型
// var obj:{[key:string]:number}={a:1,b:2}
// obj.c=3;
// obj.d=4;
// obj.e="a";
  • 定义接口类型

    • interface 大写字母 开头
    • 接口中不允许赋值
    interface IObj{
        a:number;
        b:number;
        c?:number;
    }
    ​
    var obj:IObj={a:1,b:2};
    var obj1:IObj={a:2,b:3};
    
  • 总结:

    • 如果有两个对象的类型一致时,可以定义一个接口类型

函数接口

  • 函数类型
// fn:(a:number,b:number)=>void   箭头后面的void指的是函数返回类型
// (a,b)=>  是箭头函数
const fn:(a:number,b:number)=>void=(a,b)=>{
​
}
  • 外面定义函数类型
interface IFn{
    (a:number,b:number):void;
}

const fn:IFn=(a,b)=>{
    console.log(a,b);
}
  • 接口写法
var fn:IFn=(a,b)=>{
    return a+b;
}

var fn1:(a:number,b:number,c?:number)=>number=(a,b,c)=>{
    if(c) return a+b+c;
    return a+b;
}

interface IFn{
    (a:number,b:number,c?:number):number;
}

只读接口

  • 不能被修改,不能被删除(只能是可选参数)不要设置缺省值,否则就无意义
interface IObj{
    a:number;
    b:number;
    c?:number;
    readonly d:number;
}

var obj:IObj={a:1,b:2,d:3};
var obj1:IObj={a:2,b:3,d:4};
// obj.d=10;
// delete obj.d;

下标接口

  • 包含下标的接口
interface IList{
    [index:number]:string|number
}

// var arr:IList=[1,2,"c","b"];
var arr:IList={};
arr[0]=3;
arr[1]="a";
console.log(arr)

类接口类型

  • 只要类中有这个Iclass接口中有描述的属性和方法,那么这个类实例化后的对象就认为是这个接口类型
  • 可以向下降级符合要求,也就是说:IClass中可以只定义一个,不会报错。巧合型一样

interface IClass{
    a:number;
    play():void;
}

class Box{
    a:number=1;
    constructor(){

    }
    play(){
        console.log("play")
    }
}

class Ball{
    a:number=1;
    constructor(){

    }
    play(){
        console.log("ball play")
    }
}

var b1:IClass=new Box();
var b2:IClass=new Ball();
var arr:Array<IClass>=[b1,b2];

// var arr:Array<Box|Ball>=[b1,b2];

通过类实现接口:必要实现

  • implements:实现接口,表示当前类必须满足这个接口中定义的属性和方法。也就是说interface中有什么方法,那么类中也必须要有!!
interface IUpdate{
    update():void;
}

class Box implements IUpdate{
    constructor(){

    }
    update(): void {
        console.log("aaa")
    }
}

class Ball implements IUpdate{
    constructor(){

    }
    update(): void {
        console.log("bbb")
    }
}

var arr:Array<IUpdate>=[new Box(),new Ball()];
arr.forEach((item:IUpdate)=>{
    item.update();
})

实现多个接口类型

// 定义公有类型
interface IUpdata{
    update():void
}
interface IHuman{
    name:string,
    sex:string,
    age:number
}
interface IRender{
    render():void
}
// A类型继承IUpdata,IHuman
class A implements IUpdata,IHuman{
    name:string="zhangsan"
    sex: string='男'
    age: number=20
    update(): void {
        console.log('update')
    }
}
// B类型继承IRender,IHuman
class B implements IRender,IHuman{
    name:string="wangli"
    sex: string="女"
    age: number=22
    render(): void {
        console.log('render')
    }
}
var arr:Array<IHuman>=[new A(),new B()]
console.log(arr)

构造函数接口

  • 传参时传入类类型,传入的是一个类名
interface IUpdate{
    update():void;
    // 这里是不能定义静态属性和方法,只能定义实例化
}

// 构造函数接口中才可以定义静态属性和静态方法
interface IBox{
    new (a:number,b:number):IUpdate
    a:number;//类属性  静态属性
    play():void; // 类方法  静态方法
}

class Box implements IUpdate{
    static a:number=2;
    constructor(a:number,b:number){

    }
    update(): void {
        console.log("update");
    }
    static play(){
		// 只有上面定义了类方法,这边才可以使用
    }
}
class Ball implements IUpdate{
   static  a:number=1;
    constructor(a:number,b:number){

    }
    update(): void {
        console.log("update1")
    }
}

function create(B:IBox){
    var a:IUpdate=new B(1,2);
    console.log(a);
}

create(Box);
// create(Ball);

继承接口

  • 类只能继承一个类

class A{
 a:number=1   
}
class B{
    play():void{
        console.log('play')
    }
}
class C extends B{
    
}
  • 接口继承一个接口,也可以继承多个接口
interface IA{
    a:number;	
}
interface IB{
    b:number;
}
// 接口可以继承多个接口
interface IC extends IA,IB{
    c:number;
}
class C implements IC{
    a: number=1;
    b: number=2;
    c: number=3;
}

接口继承类

  • 类中的所有属性和方法必须使用公有的
class Box{
    a:number=1;
    b:number=2;
    play():void
    {
        console.log("play")
    }
}

interface IBox extends Box{
    c:number;
}

class Ball implements IBox{
    c: number=2;
    a: number=1;
    b: number=3;
    play(): void {
        console.log("plays")
    }
}

混合类型

  • 如果在创建时无法实现这个接口定义的所有属性和方法,可以断言在增加
interface IFun{
    (a:number,b:number):void;
    num:number;
    play():void;
}

// 泛型
// var fn:IFun=<IFun>((a,b)=>{
//     console.log(a,b);
// })
var fn:IFun=((a,b)=>{
    console.log(a,b);
}) as IFun;
fn.num=3;
fn.play=function(){
    console.log("play");
}

  • 构造函数不能返回类型
  • set方法不能有返回类型
  • private 私有的
  • public 公有的
  • protected 受保护的
--实例化是否可以调用当前类中是否可以调用继承后子类是否可以调用
private 私有的不行可以不行
public 公有的可以可以可以
protected 受保护的不行可以可以
  • 总结:public(公有的)干啥都行,private (私有的)只能在类中调用,protected(受保护的) 实例化之后不能调用
  • 构造函数可以使用这三个修饰符的
  • 在当前类中,不管定义任何修饰符,都可以调用并且执行
export default class Box{
    // private  私有的
    // public  公有的
    //  protected 受保护的
    // 构造函数不能返回类型
    // 构造函数可以使用这三个修饰符的
    public a:number=1;
    protected b:number=2;
    private c:number=3;

    constructor(){
        // console.log(this.a);
        // console.log(this.b);
        // console.log(this.c);
        // this.play();
        // this.run();
        // this.jump();
        this.walk();
    }

    public play():void
    {
        console.log("play")
    }

    protected run():void
    {
        console.log("run")
    }

    private jump():void{
        console.log("jump");
        
    }
    private walk():void
    {
        console.log('walk');
        this.jump();
        this.play();
        this.run();
    }
    // set方法不能有返回类型
    // set num(value:number){

    // }
    // get num():number{
    //     return 1;
    // }
}
  • 实例化对象只能调用public定义的属性和方法

  • 只有公有的才可以调用

  • 继承后,子类可以调用父类的 public和protected定义属性和方法,private定义的不能调用

  • 继承后,

    1. 子类重新覆盖超类方法时,受保护得到可以重新定义为公有的,
    2. 但是公有的不能修改为受保护的,
    3. 在子类中不能重新覆盖创建父类的私有属性和方法
  • 总结:

    1. 如果仅在当前类中使用,实例化对象不调用,子类中不重写不调用,定义为私有的private
    2. 如果希望在子类中可以调用,重新,但是不需要实例化对象调用,不对外暴露,定义为受保护的 protected
    3. 如果希望实例化对象调用,完全调用在外的,定义为公有的public
  • 构造函数:

    1. 当构造函数设置为private私有时,意味这个类不能继承,而且也不能在其他地方实例化对象,一般来说这种写法用于单例模式(实现这个类的时候可以创建一个唯一实例化对象,可以在任何地方使用,防止实例化对象被覆盖,因此我们可以给他做一个私有的)
    2. 如果构造函数设置为protected受保护时,以为这个类不能在出除当前类和子类以外的地方实例化,可以用于继承,当前类仅用于基类不需要实例化,仅单例模式存在
    3. 如果构造函数设置为public,公有时,可以在任意位置实例化当前对象

单例模式

  • 全局的唯一一个实例化对象,可以在全局的任意一个位置调用它,可以存储值,修改值,可以抛发,可以接收事件的中建核心

静态属性

抽象类abstract

  • 类可以被继承,并不能被实例化
  • 抽象类除了具备类的特征,还有接口的特征
  • 目的就是在抽象类中实现部分基础的方法和属性,用于继承使用,而使用abstract实现抽象方法设定,需要在子类中详细描述
  • abstract static不能一起使用
  • 要求所有的属性和方法必须是public才可以使用作为接口
  • 接口中所有的属性和方法实现时,都必须是public公有的

函数

匿名函数

  • 后复制

命名函数

  • 先复制

函数知识点

  • 参数
var fn:(a: number, b: number) => void=function(a,b){
    console.log("aa")
}
  • this 参数

    • 参数类型的添加
// 鼠标点击屏蔽触发abc()函数
class Box{
    private clickFn:(e:MouseEvent)=>void;
    constructor(){
        this.clickFn=(e:MouseEvent)=>this.clickHandler(e);
        document.addEventListener("click",this.clickFn);
    }

    private clickHandler(this:Box,e:MouseEvent){
        this.abc();

    }
    private abc(){
        console.log("bac")
    }
}

new Box()
interface IObj{
    a:number;
}
function fn(this:IObj,a:number){
    this.a=a;
}

fn.call({a:1},1);

函数重载

  • 参数不一样
  • 类型不一样
function getConcat(a:string,b:string):string;
function getConcat(a:Array<number>,b:Array<number>):Array<number>;
function getConcat(a:any,b:any):any{
    if(typeof a==="string" && typeof b==="string"){
        return a+b;
    }else{
        return a.concat(b);
    }
}


var str:string=getConcat("a","b");
var arr:Array<number>=getConcat([1,2,3],[4,5,6]);
// var arr1:Array<string>=getConcat(["a","b"],["c","d"]);

泛型

  • T类型:T就是个变量,在执行它的时候执行他的变量
function getValue<T>(arg:T):T{
    return arg;
}
getValue<number>(1)  // 1
  • 一般泛型作为T,U作为第二类变量
function concat<T,U>(a:T,b:U):T|U{
    return a;
}
concat<string,number>("a",1);
// 计算得到1+2=3
interface IFn<T>{
    (a:T,b:T):void
}

var fn:IFn<number>=(a,b)=>{
    console.log(a+b);
}
fn(1,2);
  • 函数泛型接口
// interface IFn<T>{
//     (a:T,b:T):void
// }

// var fn1:IFn<number>=function(a:number,b:number):void
// {

// }
  • 泛型类型接口
// interface IFns{
//     <T>(a:T,b:T):void
// }

// function getFn<T>(a:T,b:T):void{

// }
// var fn:IFns=getFn;
// fn<number>(1,2)
  • 泛型类
class Box<T>{
    a:T;
    constructor(a:T){
        this.a=a;
    }
}

var b:Box<number>=new Box(1);
var b:Box<string>=new Box("a");