一篇博文:带你TypeScript入门,两万字肝爆,建议收藏!

Posted 贪吃ღ大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇博文:带你TypeScript入门,两万字肝爆,建议收藏!相关的知识,希望对你有一定的参考价值。

前言

ts是什么?ts其实是TypeScript的一个简称,就跟javascript简称为js一样,官方给的解释是,ts它是js的超集,其实js的代码本质上都是ts编译的,例如写一个js代码 document.write() ,上面的提示就是ts,如图:

在这里插入图片描述
系统里面写的是ts代码,所以ts是js的超集,是给js添加拓展功能的语言,这样的语言曾经还有一个叫as,但是这个语言已经没了,它其实就是flash语言。但我么开发需要完善js的话,必须得有这样的一个东西,所以微软拿着这个as的语法开发了ts这个语言,也就是说as和ts的语法基本是一样的,只不过ts是微软开发的,然后推广的不错,现在随着我们编程越来越全民化,ts使用的也就越来越多,包括在找工作中,如果你的薪资是在12k以上的话,基本上都会问你会不会ts,现在的编程很多情况下都是用到ts,因为它能给js添加拓展功能,比如:可以进行各种各样的模块化开发,像之前提到的AMD,CMD开发,CommonJS,es6的模块化规范。假设现在在客户端开发,有没有一种开发场景,既可以用AMD,也可以用CMD,CommonJS,es6的,答案是没有,因为CommonJS是只能在nodejs中使用,es6的模块化开发只能在服务器中用,它们都是有各自限制的。但是ts中,想用什么都可以,它是支持全场景的。ts它更像后端,他的语法跟java最相似,这样有什么好处?大家知道js是弱类型语言,比如一个变量先定义一个数字型,然后再重新赋值一个字符串型的,这样的话这个变量的类型就改变了,这种弱类型开发是对项目有一定的安全隐患的,比如就用这个变量去做其他事情,它有可能变成其他类型的数据,所以对开发来说是有安全隐患的,所以必须得有ts来规范js开发,消除这个安全隐患,这就是为什么ts像java、#c这些后端语言,这些强类型语言定义变量的时候,需要先声明这些变量的类型是什么,一旦定义这个变量的类型后,后期是不允许修改类型的,有了这样的规范约束后,开发就更加安全了。
现在ts使用的场景是非常广泛:js的提示(编辑器内置了规范语法的ts),主流框架vue,react在底层写框架的时候用的也是ts。

说这么多,下面直接介绍ts,也就是TypeScript。


TypeScript

简介

ts是一个给js添加特性的扩展语言。

  1. TypeScript是由微软开发的一款开源的编程语言。
  2. TypeScript是JavaScript的超集,遵循最新的es6、es5规范。TypeScript扩展了JavaScript的语法。
  3. TypeScript更像后端java、C#这样的面向对象语言,可以让js开发大型企业项目。
  4. 谷歌也在大力支持TypeScript的推广,谷歌的angular2.x+就是基于TypeScript语法。
  5. 最新的vue、React也可以集成TypeScript。
  6. nodeJs矿建Nestjs、midway中用的就是TypeScript语法。

能给js增加的功能有

  • 类型批注和编译时类型检查
  • 类型推断
  • 类型擦除
  • 接口
  • 枚举
  • Mixin
  • 泛型编程
  • 名字空间
  • 元组
  • Await
  • 模块
  • lambda 函数的箭头语法
  • 可选参数以及默认参数

js 是一个弱类型的语言,但ts是强类型的,语法很相像,但ts算是扩展的js的语法,ts通过类型注解,提供编译js时的静态类型检查。


编译

ts无法直接运行,所以只能编译成js运行。类似sass用来编译css,不能直接运行。
编译工具 - typescript

在全局任意位置下,先检测是否安装过ts

tsc --version

在这里插入图片描述

npm install -g typescript

在这里插入图片描述

检测是否安装成功:

tsc -v

ts文件的后缀是ts,编译命令:

tsc 被编译的文件

会在被编译文件的同级目录下生成一个同名的js文件。

生成自定义名称路径的文件:

tsc 被编译的文件 --outFile 编译后的文件路径

初始化命令:

tsc --init

执行初始化命令后,会生成一个tsconfig.json文件,如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AJUcQvUG-1623422064118)(media/1623161483290.png)]

其中常用配置项说明:

代表ts要转换后js版本

"target": "es5"

如果ts是以模块形式书写的,使用什么样的模块化规范,默认是commonJS

"module": "amd"

配置输出目录,可自己设置

"outDir": "./"

在这里插入图片描述

上面的配置项配置好以后,执行监视命令会自动编译:

tsc -w

使用amd规范的时候,需要将require.js文件拷贝到项目根目录下,且需要一个出口文件:

<script src="require.js" data-main="main.js"></script>

将ts编译成js,自动生成目标js文件

tsc 目标js文件

在这里插入图片描述

在这里插入图片描述


ts基础类型

在定义变量的时候需要指定类型,且定义好类型以后就不能改变他的类型了 - 强类型。

数值型

let decLiteral: number = 6; // 十进制
let hexLiteral: number = 0xf00d; // 16进制
let binaryLiteral: number = 0b1010; // 二进制
let octalLiteral: number = 0o744; // 8进制

let num: Number = 5; // 此时大写Number类型可以赋值为数值对象类型
num = new Number(10);

布尔值

let isDone: boolean = false;
let bool: Boolean = true; // 首字母大写的类型可以赋值为对象类型

boolean这种类型只能赋值两个值:true/false

var bool: boolean = true
 var bool: boolean = new Boolean(true)

Boolean这种类型除了上面的字面量方式的两个值,还可以使用构造函数方式

var bool: Boolean = false;
var bool: Boolean = new Boolean(true)

字符串

var str: string = 'asdfasdf';
var str1: String = new String('43563456')

数组

ts写的数组,其中的数据必须是同一个类型,但不指定长度
数组中所有数据的值类型必须是数字

var arr: number[] = [1,2,3];
var arr: Array<string> = ['a','b'];

声明二维数组

var arr: number[]
var brr: number[][] = [
    [1,2,3],
    [4,5,6]
];

元组 Tuple

ts中的元组表示不同类型数据组成的集合,通常会固定长度,同样可以使用下标访问元素和给元素赋值

元组中就可以放不同类型的数据
元组在定义的时候就将长度固定了

var x: [string,number] = ['a',2];
console.log(x);
console.log(x[0]);

错误

x[2] = 20

不能加长度

let x: [string, number];
x = ['hello', 10];
x[2] = 'world'; // 不能加长度

可以给元素push一个值,这个值必须是string或number的类型,其他类型不允许

x.push('aaaa')

错误

 x.push(true) // 错误

当给元组中并不存在的下标进行赋值的时候,会使用联合类型:

x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型
x[6] = true; // Error, 布尔不是(string | number)类型

枚举

ts中的枚举相当于在定义变量类型,这个类型有固定的取值范围,默认值从0开始,向后递增,使用指定的键来换换取到值,如果一个变量使用了这个类型,那他的值就必须从这个类型中选择,不能随便赋值:

枚举 - 必须使用指定的集合中的值
枚举类型,其实是给数字起了一些名字,让我们可以通过这个名字获取到对应的数字
默认情况,第一个名字对应的值是0,依次向后递增

enum Color {Red,Green,Blue};
var c: Color = Color.Blue; // 2

如果给其中某一个名字赋值了,他后面的名字对应的值,是根据这里的值向后递增

enum Color {Red,Green = 5,Blue};
var c: Color = Color.Blue; // 6

每个值可以指定

 enum Color {Red=3,Green = 4,Blue=2};
 var c: Color = Color.Blue; // 2

可以指定非数字的值

enum Color {Red='男',Green = '女',Blue='不男不女'};
var c: Color = Color.Blue; // 不男不女

通过对应值的数字获取到对应的名字 - 名字是字符串类型

enum Color {Red,Green=5,Blue};
var c: string = Color[6] // Blue

如果我们指定了其中的值是非数字型的,就不能使用这个骚操作了

enum Color {Red='red',Green = 'green',Blue='blue'};
var c: string = Color['red']; // 这个地方的值必须是数字才行

Any

Any类型,表示弱类型,也就是当我们定义一个变量的时候,不能确定变量值的类型的时候,这个类型我们又爱又恨
使用:

var a:any = 20
var b:any = 'asdfasdf'
var c:any = [1,2,3]

注意:本来我们使用ts编写代码,为的是限制类型,减少安全隐患,但是如果使用了any类型,就跟直接写js一样了,失去了意义,所以若非迫不得已,尽量不要使用。

Void

这种类型,一般用于函数执行后,不使用return返回结果的时候,就指定返回结果是void
声明变量的时候不使用它 - 当函数没有返回值的时候,返回类型指定为void


function fn(a:number,b:number):void
{
   console.log(a*b);
}

Undefined

这种类型主要用于参数和返回值,用于变量毫无意义,因为定义一个变量指定为undefined类型时,以后也就只能是undefined类型了,函数中的用法:

function fn(num:number|undefined):number|undefined
{
    return num;
}

undefined - 未定义类型

var a:undefined = undefined

定义变量不用undefined,因为定义了没有用

通常会用在函数的参数里面
希望fn函数的参数a是可选项

function fn(a:number|undefined):void
{
    console.log(a);
}

fn(undefined)

函数可选项
参数名后面,类型的冒号之前加 ? 表示这个参数是可选项
undefined通常用在函数返回值,如果返回的是undefined就需要在返回值的地方指定undefined类型

function fn(a?:number):number|undefined
{
    return a;
}
fn()

Null

null类型 - 空 - 这个数据要被销毁啦
通常在定义复杂数据类型,且在后期需要给赋值为null的时候使用

var a:number|null = 10;

使用变量a计算 - 完成

让内存回收这个变量

a = null

Never

never类型表示永远不存在的值的类型,例如,一个函数中抛出的错误,函数中有死循环永远不可能返回 …

function fn():never
{
    throw new Error('错误')
}

function fn():never
{
    return fn()
}

fn()

Object

对象类型:

var obj: object = {
    name:"张三"
}

错误写法 - 对象默认不允许添加键值对

obj.name = '张三'; 

类型断言

如果在一段代码执行后的类型种类的可能性比较多,就需要假设这是一种什么类型 - 这种操作就叫做断言。

如果一个表达式的结果有可能是多种类型,最终需要肯定其中一种

var abcd: any = [1, 2, 3, 4, 5];

断言abcd变量是一个数组

(abcd as [string,number]).push(6)
(abcd as string) += 'ddd'

函数声明

在ts中,函数定义比起js中,多了参数类型和返回值的类型定义:
函数的定义,参数的类型声明,返回值的类型声明

function fn(a:number,b:number):number
{
    // console.log(a+b);
    return a+b
}
var res = fn(1,2)

参数默认值

function fn(a:number,b:number=3):number
{
    return a+b
}

var res = fn(1)

但是在表示参数为可选项的时候,写法稍有不同:
参数可选项 - ?表示可有可无

function fn(a:number,b?:number):number
{
    if(!b){
        return a+5
    }
    return a+b
}

// var res = fn(1)
var res = fn(1,3)

带有默认值的参数,必须放在所有参数的最后面
可选项参数,必须放在所有参数的最后面

展开运算符和合并运算符同样可以使用在ts中,但是要注意运算符后面的变量的类型设置。

计算不定实参的和

function  sum(...arr:Array<number>){
    var sum = 0;
    for(var i=0;i<arr.length;i++){
        sum += arr[i]
    }
    return sum;
}

var res = sum(1,2,3);
console.log(res);

函数重载:通过 为同一个函数提供多个函数类型定义 来实现多种功能的目的。例:

function outputName(name:string):string
{
    return "我叫"+name
}

var s1 = outputName('张三')
console.log(s1);


function outputAge(age:number):string
{
    return "我今年"+age+"岁了"
}

var s2 = outputAge(12)
console.log(s2);

有多个函数结构非常类似,可以声明一个函数的结构,让函数遵循这个结构

function output(name:string):string;  定义了一个函数结构 - 名字叫output
function output(age:number):string;

function output(name:any):any
{
    return "我今年"+name+"岁了";
}

var res = output(12)
console.log(res);

var res1 = output('李四')
console.log(res1);

var res2 = output(true)  报错的,因为函数的结构要求是参数stringnumber
console.log(res2);

ts中的类

定义

定义方式跟es6的定义方式类似

class 类名{
    constructor(){

    }
}
class Person{
    // 静态属性 - 用类名直接调用的属性
    static weight:number;

    // 类的属性要定义在这里
    name:string; // 表示类中有一个属性叫name
    // 在ts类中,属性和方法前面可以加一个修饰符:
    /*
        public - 公开的 - 在哪里都能用
        protected - 受保护的
        private - 私有的
    */
    public age:number; // public可以省略的
    protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
    private height:number; // 私有的只能在类里面使用,类外面不能用
    constructor(name:string,age:number,sex:string,height:number,weight:number){
        // 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
        this.name = name

        this.age = age

        this.sex = sex

        this.height = height;

        // this.weight = weight;
        Person.weight = weight;

        this.init()
    }

    private init(){
        // console.log(this.age);
        // console.log(this.sex);
        console.log(this.height);
        console.log("这是初始化方法");
    }

    static fly(){
        console.log("飞的更高");
    }
}

var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用 

// p.init()

console.log(Person.weight);
Person.fly()

继承

ts中类的继承和es6的继承是一样,使用extends关键字,然后在构造函数中调用super函数相当于在调用父类的构造函数。

如果子类和父类有同名的方法,在子类调用这个方法的时候先在子类里面找,如果子类没有再到父类里面找。

class Person{
    // 静态属性 - 用类名直接调用的属性
    static weight:number;

    // 类的属性要定义在这里
    name:string; // 表示类中有一个属性叫name
    // 在ts类中,属性和方法前面可以加一个修饰符:
    /*
        public - 公开的 - 在哪里都能用
        protected - 受保护的
        private - 私有的
    */
    public age:number; // public可以省略的
    protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
    private height:number; // 私有的只能在类里面使用,类外面不能用
    constructor(name:string,age:number,sex:string,height:number,weight:number){
        // 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
        this.name = name

        this.age = age

        this.sex = sex

        this.height = height;

        // this.weight = weight;
        Person.weight = weight;

        this.init()
    }

    private init(){
        // console.log(this.age);
        // console.log(this.sex);
        console.log(this.height);
        console.log("这是初始化方法");
    }

    static fly(){
        console.log("飞的更高");
    }
}

var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用 

// p.init()

console.log(Person.weight);
Person.fly()

类的修饰符

在类中定义属性的时候,提供了3个修饰符:

  1. public:公有的 - 在类里面、子类中、类的外面都可以访问
  2. protected:受保护的 - 在类里面、子类中可以访问,在类外面不能访问
  3. private:私有的 - 在类里面可以访问,在子类和类的外面都不能访问

public可以省略

例:


静态属性和方法

es5中静态方法使用:

// 模拟jquery的封装
function $(element){
	return new Ele(element);
}
$.get = function(obj以上是关于一篇博文:带你TypeScript入门,两万字肝爆,建议收藏!的主要内容,如果未能解决你的问题,请参考以下文章

一篇博文带你 jQuery入门,万字肝爆! 建议收藏~

一篇博文:带你 gulp入门 0基础必看,万字肝爆,建议收藏~

1小时0基础带你Git入门,保姆式教学,万字肝爆! 建议收藏~

十几年老Java咳血推荐:MySQL索引原理失效情况,两万字肝爆,建议收藏!

一篇博文:带你用Typescript实现飞机大战,附(详细思路注释),建议收藏!

一篇博文:带你用Typescript实现飞机大战,附(详细思路注释),建议收藏!