TypeScript 基础笔记

  • 安装TypeScript
  • 编译ts
  • Typescript 开发工具 Vscode 自动编译.ts 文件
  • 数据类型
  • 布尔类型(boolean)
  • 数字类型(number)
  • 字符串类型(string)
  • 数组类型(array) ts中定义数组有两种方式
  • 元组类型(tuple) 属于数组的一种
  • 枚举类型(enum)
  • 任意类型(any)
  • null 和 undefined 其他(never类型)数据类型的子类型
  • void类型
  • never类型 是其他类型 (包括 null 和 undefined)的子类型,代表从不会出现的值
  • typeScript中的函数
  • 函数的定义
  • 可选参数
  • 默认参数
  • 剩余参数
  • 函数重载
  • 箭头函数 es6
  • es5创建对象 继承
  • typeScript中的类
  • ts中类的定义
  • 2、ts中实现继承 extends、 super
  • ts中继承的探讨 父类的方法和子类的方法一致,调用子类的方法
  • 类里面的修饰符 typescript里面定义属性的时候给我们提供了 三种修饰符
  • public :公有 在类里面、 子类 、类外面都可以访问
  • protected:保护类型 在类里面、子类里面可以访问,在类外部没法访问
  • private :私有 在类里面可以访问,子类、类外部都没法访问
  • typeScript中的泛型
  • 泛型的定义
  • 泛型函数
  • 泛型类
  • 泛型接口


安装TypeScript

npm install -g typescript

编译ts

tsc ts文件

Typescript 开发工具 Vscode 自动编译.ts 文件

vscode配置自动编译
    1.第一步   tsc --inti 生成tsconfig.json   改 "outDir": "./js",  
    2、第二步 任务 - 运行任务  监视tsconfig.json

数据类型

布尔类型(boolean)

let flag:boolean=true;

数字类型(number)

let num:number=123;

字符串类型(string)

let str:string='this is ts';

数组类型(array) ts中定义数组有两种方式

// 1.第一种定义数组的方式
    let arr:number[]=[11,22,33];
    console.log(arr);
//2.第二种定义数组的方式
    let arr:Array<number>=[11,22,33];

元组类型(tuple) 属于数组的一种

let arr:[number,string]=[123,'this is ts'];

枚举类型(enum)

<!--enum 枚举名{ 
    标识符[=整型常数], 
    标识符[=整型常数], 
    ... 
    标识符[=整型常数], 
} ;   -->  
enum Flag {success=1,error=2};
let s:Flag=Flag.success;
//    enum Color {blue,red,'orange'};


//    var c:Color=Color.red;

//    console.log(c);   //1  如果标识符没有赋值 它的值就是下标

任意类型(any)

var num:any=123;
//任意类型的用处
var oBox:any=document.getElementById('box');
oBox.style.color='red';

null 和 undefined 其他(never类型)数据类型的子类型

// var num:number;
// console.log(num)  //输出:undefined   报错

// var num:undefined;
// console.log(num)  //输出:undefined  //正确


// var num:number | undefined;
// num=123;
// console.log(num);

//一个元素可能是 number类型 可能是null 可能是undefined
var num:number | null | undefined;

void类型

//表示方法没有返回任何类型
function run():void{
    console.log('run')
}
run();

function run():number{
   return 123;
}
run();

never类型 是其他类型 (包括 null 和 undefined)的子类型,代表从不会出现的值

//这意味着声明never的变量只能被never类型所赋值。
var a:never;
//    a=123; //错误的写法
a=(()=>{
   throw new Error('错误');
})()

typeScript中的函数

函数的定义

//函数声明法
function run():string{
    return 'run';
}

//匿名函数
var fun2=function():number{
    return 123;
}
alert(fun2()); /*调用方法*/

//ts中定义方法传参
function getInfo(name:string,age:number):string{
    return `${name} --- ${age}`;
}
alert(getInfo('zhangsan',20));


//没有返回值的方法
function run():void{
    console.log('run')
}
run();

可选参数

// es5里面方法的实参和行参可以不一样,但是ts中//必须一样,如果不一样就需要配置可选参数 
function getInfo(name:string,age?:number):string{
    if(age){
        return `${name} --- ${age}`;
    }else{
        return `${name} ---年龄保密`;
    }
}
alert(getInfo('zhangsan'))
alert(getInfo('zhangsan',123))
//注意:可选参数必须配置到参数的最后
//错误写法
function getInfo(name?:string,age:number):string{
    if(age){
        return `${name} --- ${age}`;
    }else{
        return `${name} ---年龄保密`;
    }
}
alert(getInfo('zhangsan'))

默认参数

// es5里面没法设置默认参数,es6和ts中都可以设置默认参数
function getInfo(name:string,age:number=20):string{
    if(age){
        return `${name} --- ${age}`;
    }else{
        return `${name} ---年龄保密`;
    }
}
// alert( getInfo('张三'));
alert( getInfo('张三',30));

剩余参数

function sum(a:number,b:number,c:number,d:number):number{
   return a+b+c+d;
}
alert(sum(1,2,3,4));
//三点运算符 接受新参传过来的值
function sum(...result:number[]):number{
    var sum=0;
    for(var i=0;i<result.length;i++){
        sum+=result[i];  
    }
    return sum;
}
alert(sum(1,2,3,4,5,6)) ;

function sum(a:number,b:number,...result:number[]):number{
    var sum=a+b;
    for(var i=0;i<result.length;i++){
        sum+=result[i];  
    }
    return sum;
}
alert(sum(1,2,3,4,5,6)) ;

函数重载

// java中方法的重载:重载指的是两个或者两个以上同名函数,但它们的参数不一样,这时会出现函数重载的情况。
// typescript中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
//ts为了兼容es5 以及 es6 重载的写法和java中有区别。

//es5中出现同名方法,下面的会替换上面的方法 
function css(config){
}
function css(config,value){
}

//ts中的重载 通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
function getInfo(name: string): string;
function getInfo(age: number): string;
function getInfo(age: Array<number>): string;
function getInfo(str: any): any {
    if (typeof str === 'string') {
        return '我叫:' + str;
    } else {
        return '我的年龄是' + str;
    }
}
alert(getInfo('张三'));   //正确
alert(getInfo(20));   //正确
alert(getInfo([1]));    //正确
alert(getInfo(true));    //错误写法

function getInfo(name:string):string;
function getInfo(name:string,age:number):string;
function getInfo(name:any,age?:any):any{
    if(age){

        return '我叫:'+name+'我的年龄是'+age;
    }else{

        return '我叫:'+name;
    }
}
alert(getInfo('zhangsan'));  /*正确*/
alert(getInfo('zhangsan',20));
alert(getInfo(123));  //错误

箭头函数 es6

//this指向的问题 箭头函数里面的this指向上下文
setTimeout(()=>{
    alert('run')
},1000)

es5创建对象 继承

// es5里面的类

  //1.最简单的类
  function Person() {
    this.name = "张三";
    this.age = 20;
  }
  var p = new Person();
  alert(p.name);

  //2、构造函数和原型链里面增加方法

  function Person() {
    this.name = "张三"; /*属性*/
    this.age = 20;
    this.run = function() {
      alert(this.name + "在运动");
    };
  }
  // //原型链上面的属性会被多个实例共享   构造函数不会
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };
  var p = new Person();
  // alert(p.name);
  // p.run();
  p.work();

  //3类里面的静态方法
  function Person() {
    this.name = "张三"; /*属性*/
    this.age = 20;
    this.run = function() {
      /*实例方法*/

      alert(this.name + "在运动");
    };
  }

  Person.getInfo = function() {
    alert("我是静态方法");
  };
  //原型链上面的属性会被多个实例共享   构造函数不会
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };
  var p = new Person();
  p.work();

  //调用静态方法
  Person.getInfo();

  // 4、es5里面的继承   对象冒充实现继承

  function Person() {
    this.name = "张三"; /*属性*/
    this.age = 20;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  //Web类 继承Person类   原型链+对象冒充的组合继承模式

  function Web() {
    Person.call(this); /*对象冒充实现继承*/
  }

  var w = new Web();
  // w.run();  //对象冒充可以继承构造函数里面的属性和方法

  w.work(); //对象冒充可以继承构造函数里面的属性和方法   但是没法继承原型链上面的属性和方法

  // 5、es5里面的继承   原型链实现继承

  function Person() {
    this.name = "张三"; /*属性*/
    this.age = 20;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  //Web类 继承Person类   原型链+对象冒充的组合继承模式

  function Web() {}

  Web.prototype = new Person(); //原型链实现继承
  var w = new Web();
  //原型链实现继承:可以继承构造函数里面的属性和方法 也可以继承原型链上面的属性和方法
  //w.run();

  w.work();

  // 6、 原型链实现继承的 问题?

  function Person(name, age) {
    this.name = name; /*属性*/
    this.age = age;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  var p = new Person("李四", 20);
  p.run();

  function Person(name, age) {
    this.name = name; /*属性*/
    this.age = age;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  function Web(name, age) {}

  Web.prototype = new Person();

  var w = new Web("赵四", 20); //实例化子类的时候没法给父类传参

  w.run();

  // var w1=new Web('王五',22);

  //7.原型链+对象冒充的组合继承模式

  function Person(name, age) {
    this.name = name; /*属性*/
    this.age = age;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  function Web(name, age) {
    Person.call(this, name, age); //对象冒充继承   实例化子类可以给父类传参
  }

  Web.prototype = new Person();

  var w = new Web("赵四", 20); //实例化子类的时候没法给父类传参

  // w.run();
  w.work();

  // var w1=new Web('王五',22);

  //8、原型链+对象冒充继承的另一种方式

  function Person(name, age) {
    this.name = name; /*属性*/
    this.age = age;
    this.run = function() {
      /*实例方法*/
      alert(this.name + "在运动");
    };
  }
  Person.prototype.sex = "男";
  Person.prototype.work = function() {
    alert(this.name + "在工作");
  };

  function Web(name, age) {
    Person.call(this, name, age); //对象冒充继承  可以继承构造函数里面的属性和方法、实例化子类可以给父类传参
  }

  Web.prototype = Person.prototype;

  var w = new Web("赵四", 20); //实例化子类的时候没法给父类传参

  w.run();
  // w.work();

  // var w1=new Web('王五',22);

typeScript中的类

ts中类的定义

es5:
    function Person(name){
        this.name=name; this.run=function(){   console.log(this.name)
        }
    }
    var p=new Person('张三');
    p.run()
ts中定义类:
class Person{
    name:string;   //属性  前面省略了public关键词
    constructor(n:string){ //构造函数实例化类的时候触发的方法
        this.name=n;
    }
    run():void{
        alert(this.name);
    }
    getName():string{
        return this.name;
    }
    setName(name:string):void{
        this.name=name;
    }
}
var p=new Person('张三');
p.run()

2、ts中实现继承 extends、 super

class Person{
    name:string;
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
var p=new Person('王五');
alert(p.run())
class Web extends Person{
    constructor(name:string){
        super(name);  /*初始化父类的构造函数*/
    }
}
var w=new Web('李四');
alert(w.run());

ts中继承的探讨 父类的方法和子类的方法一致,调用子类的方法

class Person{
    name:string;
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
// var p=new Person('王五');
// alert(p.run())
class Web extends Person{
    constructor(name:string){
        super(name);  /*初始化父类的构造函数*/
    }
    run():string{
        return `${this.name}在运动-子类`
    }
    work(){
        alert(`${this.name}在工作`)
    }
}
var w=new Web('李四');
// alert(w.run());
// w.work();
alert(w.run()); // 李四在运动-子类

类里面的修饰符 typescript里面定义属性的时候给我们提供了 三种修饰符

public :公有          在当前类里面、 子类  、类外面都可以访问
protected:保护类型    在当前类里面、子类里面可以访问,在类外部没法访问
private :私有         在当前类里面可以访问,子类、类外部都没法访问

public :公有 在类里面、 子类 、类外面都可以访问

class Person{
    public name:string;  /*公有属性*/
    constructor(name:string){
        this.name=name;
    }
    run():string{

        return `${this.name}在运动`
    }
}
var p=new Person('王五');
alert(p.run())
class Web extends Person{
    constructor(name:string){

        super(name);  /*初始化父类的构造函数*/
    }
    run():string{
        return `${this.name}在运动-子类`
    }
    work(){
        alert(`${this.name}在工作`)
    }
}
var w=new Web('李四');
w.work();

//类外部访问公有属性
class Person{
    public name:string;  /*公有属性*/
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
var  p=new Person('哈哈哈');
alert(p.name);

protected:保护类型 在类里面、子类里面可以访问,在类外部没法访问

class Person {
    protected name: string;  /*公有属性*/
    constructor(name: string) {
        this.name = name;
    }
    run(): string {
        return `${this.name}在运动`
    }
}
var p = new Person('王五');
alert(p.run())
alert(p.name) // 报错
class Web extends Person {
    constructor(name: string) {
        super(name);  /*初始化父类的构造函数*/
    }
    work() {
        alert(`${this.name}在工作`)
    }
}
var w = new Web('李四11');
w.work();
alert(w.run());

//类外外部没法访问保护类型的属性
class Person{
    protected name:string;  /*保护类型*/
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
var  p=new Person('哈哈哈');
alert(p.name);

private :私有 在类里面可以访问,子类、类外部都没法访问

class Person{
    private name:string;  /*私有*/
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
class Web extends Person{
    constructor(name:string){
        super(name)
    }
    work(){
        console.log(`${this.name}在工作`) // 报错
    }
}

class Person{
    private name:string;  /*私有*/
    constructor(name:string){
        this.name=name;
    }
    run():string{
        return `${this.name}在运动`
    }
}
var p=new Person('哈哈哈');
alert(p.run());

typeScript中的泛型

泛型的定义

泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

//只能返回string类型的数据
function getData(value:string):string{
   return value;
}


//同时返回 string类型 和number类型  (代码冗余)
function getData1(value:string):string{
    return value;
}
function getData2(value:number):number{
    return value;
}

//同时返回 string类型 和number类型       any可以解决这个问题
function getData(value:any):any{
    return '哈哈哈';
}
getData(123);
getData('str');

//any放弃了类型检查,传入什么 返回什么。比如:传入number 类型必须返回number类型  传入 string类型必须返回string类型
//传入的参数类型和返回的参数类型可以不一致
//    function getData(value:any):any{
//         return '哈哈哈';
//     }

泛型函数

泛型:可以支持不特定的数据类型   要求:传入的参数和返回的参数一直

// T表示泛型,具体什么类型是调用这个方法的时候决定的
function getData<T>(value:T):T{
   return value;
}
getData<number>(123);
getData<string>('1214231');
getData<number>('2112');       /*错误的写法*/  



function getData<T>(value:T):any{
   return '2145214214';
}
getData<number>(123);  //参数必须是number
getData<string>('这是一个泛型');

泛型类

//泛型类:比如有个最小堆算法,需要同时支持返回数字和字符串 a  -  z两种类型。  通过类的泛型来实现
class MinClass{
    public list:number[]=[];
    add(num:number){
        this.list.push(num)
    }
    min():number{
        var minNum=this.list[0];
        for(var i=0;i<this.list.length;i++){
            if(minNum>this.list[i]){
                minNum=this.list[i];
            }
        }
        return minNum;
    }

}
var m=new MinClass();
m.add(3);
m.add(22);
m.add(23);
m.add(6);
m.add(7);
alert(m.min());


//类的泛型
class MinClas<T>{
    public list:T[]=[];
    add(value:T):void{
        this.list.push(value);
    }
    min():T{        
        var minNum=this.list[0];
        for(var i=0;i<this.list.length;i++){
            if(minNum>this.list[i]){
                minNum=this.list[i];
            }
        }
        return minNum;
    }
}
var m1=new MinClas<number>();   /*实例化类 并且制定了类的T代表的类型是number*/
m1.add(11);
m1.add(3);
m1.add(2);
alert(m1.min())


var m2=new MinClas<string>();   /*实例化类 并且制定了类的T代表的类型是string*/

m2.add('c');
m2.add('a');
m2.add('v');
alert(m2.min())

泛型接口

//函数类型接口
interface ConfigFn{
    (value1:string,value2:string):string;
}
var setData:ConfigFn=function(value1:string,value2:string):string{
    return value1+value2;
}
setData('name','张三');

//1、泛型接口
interface ConfigFn{
    <T>(value:T):T;
}
var getData:ConfigFn=function<T>(value:T):T{
    return value;
}
// getData<string>('张三');
// getData<string>(1243);  //错误

//2、泛型接口
interface ConfigFn<T>{
    (value:T):T;
}
function getData<T>(value:T):T{
    return value;
}
var myGetData:ConfigFn<string>=getData;     
myGetData('20');  /*正确*/
// myGetData(20)  //错误