TypeScript学习总结

Posted 面条请不要欺负汉堡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript学习总结相关的知识,希望对你有一定的参考价值。

TypeScript简单说明

TypeScript 是由微软开发的一款开源的编程语言,是 javascript 的一个超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发。添加了类型系统的 JavaScript,适用于任何规模的项目。

什么是 TypeScript?

TypeScript 是添加了类型系统的 JavaScript,适用于任何规模的项目。
TypeScript 是一门静态类型、弱类型的语言。
TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性。
TypeScript 可以编译为 JavaScript,然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。
TypeScript 拥有很多编译选项,类型检查的严格程度由你决定。
TypeScript 可以和 JavaScript 共存,这意味着 JavaScript 项目能够渐进式的迁移到 TypeScript。
TypeScript 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
TypeScript 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
TypeScript 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。

特性

  1. 类型系统

「类型」是其最核心的特性。

类型系统按照「类型检查的时机」来分类,可以分为动态类型和静态类型。

动态类型是指在运行时才会进行类型检查,这种语言的类型错误往往会导致运行时错误。

静态类型是指编译阶段就能确定每个变量的类型,这种语言的类型错误往往会导致语法错误。

TypeScript 是弱类型

类型系统按照「是否允许隐式类型转换」来分类,可以分为强类型和弱类型

  1. 适用于任何规模

配置

tsc --init 生成tsconfig.json
vscode 任务-运行任务 tsc:监视-tsconfig.json

运行项目

第一方式:

1 命令 在文件目录下

    tsc hello.ts 编译
    这时可以看到目录下生成 hello.js 里面内容就是刚刚创建的

2.执行 node hello.js  这时就可以执行js内容 

    输出:hello Yee

第二种 利用开发工具自动编译.ts文化

在项目cd E:\\gitProgram\\gitee\\tsc

1 生产配置文件tsconfig.json
tsc --init 

修改tsconfig.json文件:     "outDir": "./js",     


2 vscode 工具:终端-》运行任务-》TypeScript-》tsc 监视 tsconfig.json  
 生产js/index.js 文件

语法

数据类型

原始数据类型包括:布尔值、数值、字符串、null、undefined 以及 ES6 中的新类型 Symbol 和 ES10 中的新类型 BigInt

  • boolean

let isDone: boolean = false;
注意,使用构造函数 Boolean 创造的对象(let createdByNewBoolean: boolean = new Boolean(1) )不是布尔值:

  • number
    let decLiteral: number = 20;//十进制
    let hexLiteral: number = 0x14; //十六进制0x
    let binaryLiteral: number = 0b10100;//二进制 0 1
    let octalLiteral: number = 0o24;//八进制

  • string
    let myName: string = ‘Tom’;
    // 模板字符串
    let sentence: string = Hello, my name is ${myName}.

  • void
    空值 void 类型 一般用于 定义方法的时候没有返回值
    void 表示没有任何返回值的函数,声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null

  • 元组类型tuple
    let arr:[string,number,boolean] = [“tes”, 1, false]

  • 枚举类型enum

enum Color {
    red,
    blue,
    yellow = 5,
}
let color:Color = Color.yellow // 5
color = Color.yellow // 0, 未赋值则输出下标
  • 任意类型any
    任意值(Any)用来表示允许赋值为任意类型。
    any 类型,则允许被赋值为任意类型。
    let myFavoriteNumber: any = ‘seven’;
    myFavoriteNumber = 7;
    声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值。
    变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型
    let something;
    something = ‘seven’;
    something = 7;
    用处:不知道变量得类型时,可以定义任意类型
    var oBox:any = document.getElementById(‘box’)
    oBox.style.color=‘red’ //修改颜色

  • null和undefined是其他(never)类型的子类型
    与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量,而 void 类型的变量不能赋值给 number 类型的变量。nerver的变量只能被nerver类型所赋值

let u: undefined = undefined;
let n: null = null;
// 这样不会报错
let num: number = undefined;
// 这样也不会报错
let u: undefined;
let num: number = u;
    let u: void;
let num: number = u; //报错

函数

两种常见的定义函数的方式——函数声明(Function Declaration)和函数表达式(Function Expression)


1. es5 :
// 函数声明(Function Declaration)
function sum(x, y) {
    return x + y;
}

// 函数表达式(Function Expression)
let mySum = function (x, y) {
    return x + y;
};

2. ts 函数声明(ts)
function sum(x: number, y: number): number {
    return x + y;
}
注意,输入多余的(或者少于要求的)参数,是不被允许的:
function sum(x: number, y: number): number {
    return x + y;
}
sum(1, 2, 3);//错误
sum(1);//错误

3. ts 函数表达式(ts)
let mySum = function (x: number, y: number): number {
    return x + y;
};

let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
};

注意:不要混淆了 TypeScript 中的 => 和 ES6 中的 =>
在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
在 ES6 中,=> 叫做箭头函数,

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

// 匿名表达式
var run2 = function():string {
    return '123'
}

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

// 方法可选参数(age可传,可不传)
// 可选参数要放在所有参数的最后
function getInfo(name: string, age?: number):string {
    if (age) {
        return `${name}:${age}`
    }
    return `${name}`
}

// 默认参数
function getInfo(name: string, age: number = 20):string {
    if (age) {
        return `${name}:${age}`
    }
    return `${name}`
}

// 剩余参数(基于三点运算符)
function sum(a: number, b:number, c:number, d:number):number {
    return a + b + c + d;
}
可改为
function sum(a: number, ..res: number[]):number {
 var sum =a;
    for(var i =0;i<arr.length;i++){
        sum +=arr[i]
    }
    return sum
}
sum(1,2,3,4,5)// 这边就会默认a 传的是1 ,其他的剩下 都是arr 的值

补充:

用接口定义函数的形状

interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
采用函数表达式|接口定义函数的方式时,对等号左侧进行类型限制,可以保证以后对函数名赋值时保证参数个数、参数类型、返回值类型不变。

重载

js 是面对对象的语言,它是没有重置的。
ts中的重载:通过为同一个函数提供多个函数类型定义来试下多种功能的目的。
ts 为了兼容es5以及es6重载的写法。

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

  2. ts函数重载

function getInfo(name: string): string;
function getInfo(age: number): number;

function getInfo(arg: any): any {
  return 123;
}

es5 的类

1. 简单的类
function Person(){
    this.name ='张三'
    this.age=20
}
var p =  Person()
alert(p.name)

2.构造函数和原型链里面的增加方法

构造函数增加方法
function Person(){
    this.name ='张三' //属性
    this.age=20
    this.run =function(){//实例方法  是需要new 实例化 才可以
        alert(this.name+'在运动')
    }
}
原型链里面的增加方法(原型链上面的属性会被多个实例共享,构造函数不会)
Person.prototype.age='男'
Person.prototype.work = function(){//方法
    alert(this.name+'在工作')
}
var p = new Person()
alert(p.name)
p.run()
p.work()

3. 静态方法(基于2的基础)
    Person.getInfo = function(){....}

    调用静态方法
    Person.getInfo()

静态方法调用不需要new  实例化 ,

4. es5里面的继承
function Person(){
    this.name ='张三' //属性
    this.age=20
    this.run =function(){//实例方法  是需要new 实例化 才可以
        alert(this.name+'在运动')
    }
}
Person.prototype.age='男'
Person.prototype.work = function(){//方法
    alert(this.name+'在工作')
}
Web类 继承Person继承 

a. 对象冒充继承方式
function Web(){
    Person.call(this)//对象冒充实现继承
}
var w =new Web()
w.run()
w.work()//错误

注意:对象冒充可以继承构造函数的属性和方法,但是不能继承原型链的属性和方法

b . 原型链继承
function Web(){}
Web.prototype =new Person();//原型链实现继承方法
var w =new Web()
w.run()
w.work()

注意:原型链实现继承:可以继承构造函数的属性和方法,也可以继承原型链上的属性和方法,但是实例化子类的时候 没法给父类传参

如问题:
function Person(name,age){
    this.name =name
    this.age=age
    this.run =function(){//实例方法  是需要new 实例化 才可以
        alert(this.name+'在运动')
    }
}

Person.prototype.age='男'
Person.prototype.work = function(){//方法
    alert(this.name+'在工作')
}


var w =new  Person('张三',20)
w.run()//张三 在运行


现在用继承后
function Web(name,age){}
Web.prototype =new Person();//原型链实现继承方法
var w =new Web('王一',20)
w.run()// undefined在运行

所以 可以看出: 使用原型链实现继承后,实例化子类的时候 没法给父类传参


c. 原型链+对象冒充的组合继承模式(推荐)


function Person(name,age){
    this.name =name
    this.age=age
    this.run =function(){//实例方法  是需要new 实例化 才可以
        alert(this.name+'在运动')
    }
}

Person.prototype.age='男'
Person.prototype.work = function(){//方法
    alert(this.name+'在工作')
}

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

Web.prototype =new Person(); 或者是 Web.prototype =Person.prototype ; //原型链实现继承方法

var w =new  Person('赵四',20)

w.run()//赵四 在运行
w.work()//赵四 在工作

ts 中定义类

class Person{
    name:string;//属性 前面省略了public 关键词
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    getName():void{
        alert(this.name);
    }
    setName(name:string):void{
        this.name =name
    }
}

var p  = new Person('张三')
p.getName()


(1)继承 extends  super 配合使用

1.继承

class Web extends Person{
    constructor(name:string){
       super(name)// 初始化父类的构造函数
    }
}

var w =new Person('隶属')
w.getName() //隶属

2. ts 中继承的探讨 父类的方法和子类的方法名一致时,是调用子类的方法

class Web extends Person{
    constructor(name:string){
       super(name)// 初始化父类的构造函数
    }
    work(){
        alert(this.name);
    }
    getName():void{
        alert(this.name+'在运动');
    }
}

var w =new Web('张一')
// w.getName()

// w.work()

w.getName()//张一在运动


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

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

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

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

属性如果不加修饰符的话,默认是公有public

1. public 公有的  在类里面、子类、类外面都可以访问

class Person{
    public name:string;//属性 前面省略了public 关键词
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    getName():void{
        // 类里面可以访问
        alert(this.name);
    }
    setName(name:string):void{
        this.name =name
    }
}
class Web extends Person{
    constructor(name:string){
       super(name)// 初始化父类的构造函数
    }
    work(){
        alert(this.name);
    }
    getName():void{
        alert(this.name+'在运动');
    }
}

var w =new Web('张一')
//子类 Web 的方法 work 也可以访问name
w.work()
//类外面都可以访问
var p  = new Person('张三')
console.log(p.name)


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

class Person{
    protected name:string;//属性 
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    getName():void{
        // 类里面可以访问
        alert(this.name);
    }
    setName(name:string):void{
        this.name =name
    }
}
class Web extends Person{
    constructor(name:string){
       super(name)// 初始化父类的构造函数
    }
    work(){
        console.log('protected:保护类型 ----',this.name);
    }
    getName():void{
        alert(this.name+'在运动');
    }
}

var w =new Web('张一')
//子类 Web 的方法 work 也可以访问name
w.work()//protected:保护类型 ---- 张一

// //类外面都可以访问
var p  = new Person('张三')
// console.log(p.name)//报错


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

class Person{
    private name:string;//属性 
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    getName():void{
        // 类里面可以访问
        alert(this.name);
    }
    setName(name:string):void{
        this.name =name
    }
}
class Web extends Person{
    constructor(name:string){
       super(name)// 初始化父类的构造函数
    }
    work(){
        console.log('protected:保护类型 ----',this.name);
    }
    getName():void{
        alert(this.name+'在运动');
    }
}

var w =new Web('张一')
//子类 Web 的方法 work 也可以访问name
w.work()//报错

// //类外面都可以访问
var p  = new Person('张三')
console.log(p.name)//报错

(3) 类的静态属性 静态方法(有 static 就是静态方法)

1. es5 静态属性 静态方法/实例方法

function Person(){
    this.work = function(){//实例方法: 实例方法调用,必须var  p  = new Person() p.work()

    }
    
}
Person.name ='张三'//静态属性
Person.run = function(){//静态方法

}

var  p  = new Person()
Person.run()//静态方法调用

2. ts 静态属性 静态方法/实例方法

class Person{
    name:string;//属性 
    static age:number=20;
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    work(){//实例方法 实例方法调用,必须var  p  = new Person() p.work()
        console.log('ts 实例方法:',this.name+'在工作')
    }
    static print(){// 含有 static 就是静态方法
        console.log('ts 静态方法:') // 静态方法调用  Person.print()  
        // console.log('ts 静态方法:',this.name) // 静态方法 没办法直接调用类里的属性,只有把属性改成静态属性 则就可以调用
    }
}
var  p  = new Person('张三')
Person.print()
console.log('ts 静态属性',Person.age)//ts 静态属性 20   只有把属性改成静态属性 ,则就可以调用


a. 实例化  :实例方法调用,必须var  p  = new Person() p.work()
b.含有 static方法 就是静态方法,静态方法调用  Person.print() ;静态方法 没办法直接调用类里的属性
c.含有 static 变量就是静态属性,则就可以调用

(4) 多态:父类定一个方法不去实现,让继承它的子类区实现,每一个子类有不同的表现

多态也属于继承的一类

class Animal{
    name:string;
    constructor(n:string){//构造函数 实例化类的时候触发的方法
        this.name=n
    }
    eat(){
        console.log('吃的方法:')//具体吃啥没说 而是在子类里面一一针对
    }
}
class Dog extends Animal{
    constructor(n:string){
        super(n)
    }
    eat(){
        return this.name+'吃狗粮'
    }
}

class Cat extends Animal{
    constructor(n:string){
        super(n)
    }
    eat(){
        return this.name+'吃猫粮'
    }
}

(5) 抽象类,抽象方法

ts中的抽象类:它是提供其他类继承的基类,不能直接被实例化

用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类(子类)中实现

abstract 抽象方法只能放在抽象类里面

抽象类和抽象方法用来定义标准。

eg  : Animal这个类要求它的子类必须包含eat方法

abstract class  Animal {
    name:string;
    constructor(n:string){
        this.name =n
    }
    abstract eat():any;//抽象类的子类必须实现抽象类里面的方法
}
// var a = new Animal()//提供其他类继承的基类,不能直接被实例化 这个是错误

class Dog extends Animal{

    constructor(name:any){
        super(name)
    }
    // 抽象类的子类必须实现抽象类里面的方法
    eat(){
        console.log(this.name+'吃狗粮')
    }
}
var d = new Dog('旺财')
d.eat()// 旺财吃狗粮

接口

接口作用
在面对对象的编程中,接口时一种规范的定义,它定义了行为和动作的规范,在程序设计里面,接口起到一种限制和规范的作用。接口定义了某一批类所需要的遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。ts中接口类似Java,同时还增加了更灵活的接口类型,包括属性,函数,可索引和类等

(1) 属性类接口 ---对json 的约束

1. ts的定义方法

function printLable():void{
    console.log('定义方法')
}

printLable();

2. ts的定义方法 传递参数

function printLable(label:string):void{
    console.log('定义方法:',label)
}

printLable('参数一');

3. ts 中定义方法传入的参数 对json进行约束


function printLable(params:{label:string}):void{
    console.log('定义方法:',params.label)
}

printLable('参数一');//错误

printLable({name:'参数一'});//错误

printLable({label:'参数一1'});//正确  定义方法: 参数一1

4. 对批量方法传入参数进行约束

接口:行为和动作的规范,对批量方法进行约束

    // 定义接口
    interface FullName{
        firstName:string;
        secondName:string;
    }

    function printName(name:FullName){
        //必须传入 firstName  secondName
        console.log(name.firstName+'---'+name.secondName)
    }

    printName('111')//报错
    //如果时以下这种方式的话,传递的参数 必须跟接口一致,或者会报错
    printName({
        age:20,//多传一个就报错
        firstName:'王',
        secondName:'依'
    })

    var obj ={
        age:20,
        firstName:'王',
        secondName:'依'
    }
    printName(obj)//这样的传对象的话, 只要含有接口定义的参数(正确的参数,类型也是对的),都是正确的 王---依

    // 批量的时候

    function printInfos(infos:FullName){
        //必须传入 firstName  secondName
        console.log(infos.firstName+'---'+infos.secondName+'-----1111')
        //虽然参数可以多传,但是在使用中,必须和接口定义的参数一致,否则会报错
        // console.log(infos.firstName+'---'+infos.secondName+'---'+infos.age)
    }
    printInfos(obj)//王---依-----1111

5. 接口:可选属性

    interface FullName{
        firstName:string;
        secondName:string;
        age?:number
    }

    function printName(name:FullName){
        //必须传入 firstName  secondName
        console.log(name.firstName+'---'+name.secondName)
    }
printName({
    firstName:'王',
    secondName:'依'
})
//age 可选可不选


eg:  接口和ajax

$.ajax({
    type:'GET',
    url:'test.json',
    data:{name:$('#name').val(),pass:$('#pass').val()}
    dataType:'json'
})

接口定义
interface Config{
    type:string;
    url:string;
    data?:string;
    dataType:string;
}

function ajax(config:Config){
    var 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('成功')
        }
    }
}

ajax({
    type:'get',
    url:'http://192.168.5.97:8000/user',
    dataType:'json'
})


(2) 函数类接口:对方法传入的参数,以及返回值进行约束

1. 加密的函数类型接口
interface encrypt{
    (key:string,value:string):string
}

var md5:encrypt = function(key:string,value:string):string{
    //模拟操作
    return key+value
}
console.log(md5('111','zhangyi'))//111zhangyi

(3) 可索引类接口:数组、对象的约束(不常用)


//定义数组的约束
var arr:number[]=[11,222]

1. 可索引类接口  : 针对数组
interface UserArr{
    [index:number]:string
}
var arr:UserArr =['1','22111'以上是关于TypeScript学习总结的主要内容,如果未能解决你的问题,请参考以下文章

Python学习总结

typescript Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming/angular-2/

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming

typescript Angular最终版本的Angular 2测试片段。代码库https://developers.livechatinc.com/blog/category/programming

TypeScript学习总结