一、什么是TypeScript

以javaScript 为基础构建的语言,可以在任何支持javaScript的平台中运行,Ts不能被js解析器直接执行,需要将ts文件编译成js文件一个javaScript的超集,TypeScript扩展了JavaScript并添加了类型

二、TypeScript增加了什么

(1)类型 (2)支持ES的新特性 (3)添加Es不具备的新特性 (4)丰富的配置选项 (5)强大的开发工具

三.TypeScript开发环境搭建

> (1)下载node.js,安装node.js

> (2)使用npm全局安装TypeScript

> ①进入命令行

> ②输入:npm i -g typescript

> (3)创建一个ts文件

> (4)适用ts对ts文件进行编译

> ①进入命令行

> ②进入ts文件所在目录

> ③执行命令tsc xxx.ts

四、基本类型

类型声明:

1)类型声明是TS非常重要的一个特点 2)通过类型声明可以指定TS中变量(参数、形参)的类型 3)指定类型后,当为变量赋值时,TS编译器会自动检查是否符合类型声明,符合则赋值,否则报错 4)简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值

语法:

let 变量:类型;

let 变量:类型 = 值;

function fn(参数:类型,参数:类型):类型 {

}

自动类型判断:

a.Ts拥有自动的类型判断机制 b.当对变量的声明和赋值是同时进行的,ts编译器会自动判断变量的类型 c.所以如果你的变量的声明和赋值是通过是进行的,可以省略掉类型声明。

类型:

类型例子描述number1,-33,2.5任意数字String‘hi’,”h1”,hi任意字符串BooleanTrue,false布尔值true或false

字面量其本身限制变量的值就是该字面量的值Any*任意类型Unknown*类型安全的anyVoid空值(undefined)没有值或undefinedNever没有值不能是任何值Object{name:’孙悟空’}任意的js对象Array[1,2,3]任意js数组Tuple[4,5]元素,TS新增类型,固定长度数组EnumEnum{A,B)枚举,TS中新增类型

类型使用样例:

//let a:string

// 也可以直接使用字面量进行类型声明

let a:10 // 字面量相当于常量,他不能被修改

// 可以使用|连接多个类型(联合类型)

let b:'male' | 'female'; //声明b可以是male 或者female

let c:boolean|string;

/Any///

// any 表示的是任意类型,一个变量设置类型为any后相当于对该变量关闭了ts的类型检测

// 使用TS时,不建议使用any类型

// let d:any; 显式any

// 声明变量如果不指定类型,则TS解析器会自动判断类型变量的类型为any(隐式any)

let d;

d = 10;

d = 'hello'

d = false

d = {}

let s:string;

// d的类型式any,它可以赋值给任意变量

s = d;

// unknown 表示未知类型的值

let e:unknown;

e = 10;

e = 'hello';

e = true

let t:string;

// e的类型是unknown未知的类型,将它赋值给已知类型string时会报错:Type 'unknown' is not assignable to type 'string'.ts(2322)

// t = e;

//unknown 实际上是一个类型安全的any,unknown类型的变量不能直接赋值给其他变量

// 解决办法1:

if(typeof e === 'string') {

t = e

}

// 解决办法2:类型断言:可以用来告诉解析器变量的实际类型(意思是我们知道e是字符串,编译器不知道,

// 我们告诉编译器它就是字符串,让它放心的用吧)

/**

* 类型断言:

* 语法:

* 变量 as 类型

* <类型>变量

*/

s = e as string;

//或写成

s = e;

// void 用来表示返回值为空,以函数为例,就表示没有返回值函数

function fn():void{

// return '123' // 当返回值为void时,会报错Type 'string' is not assignable to type 'void'.ts(2322),可以写成return;或者return undefined;或者return null;

}

// never 表示永远不会返回结果

function fn2():never{

throw new Error('报错了');

// return '123' // 当返回值为void时,会报错Type 'string' is not assignable to type 'void'.ts(2322),可以写成return;或者return undefined;或者return null;

}

// object表示一个js对象,不常用,因为万物皆对象,

let f:object;

f = {};

f = function(){}

//object 常用方式如下:

// {} 用来指定对象中可以包含哪些属性

// 语法:{属性名:属性类型}

// 在属性名后面加上?,表示属性是可选的

let g:{name:string, age?:number} //?表示这个属性后面赋值有也行,没有也行

g={name:'孙悟空'};

// [propName: string]: any 表示任意类型的属性

let h: {name: string,[propName: string]: any}

h = {name: '猪八戒', age: 18}

/*

*设置函数结构的类型声明

语法:(形参:类型,形参:类型...)=>返回值

*/

let i:(a:number,b:number)=>number;

// i = function (n1, n2):number{

// return n1 + n2;

// }

/**

* 数组的类型声明:

* 类型[];

* Array<类型>

*/

// string[]表示字符串数组

let j:string[];

let k:Array;

let l:Array;

/**

* 元组:元组就是固定长度的数组

* [类型,类型,类型]

*/

let m:[string,string]

m = ['孙悟空','猪八戒']

/**

* 枚举

*/

enum Gender{

Male = 0,

female = 1

}

let n:{name:string,gender:Gender}

n={

name: '孙悟空',

gender: Gender.Male

}

console.log(n.gender === Gender.Male)

//类型的别名

type mytype = 1|2|3|4|5;

let r:mytype

r=5;

//r=6; // Type '6' is not assignable to type 'mytype'.ts(2322)

五、Ts编译配置

项目新建tsconfig.json

{

/*tsconfig.json 是ts编译器的配置文件,ts编译器可以根据她的信息来对代码进行编译

"include": ["],用来指定哪些ts文件需要被编译,一个/*表示任意文件,两个/**表示任意文件目录

"exclude": 不需要被编译的目录,默认值["node_modules","bower_components","jspm_packages"]

"extends":"", 继承,如果我有两个tsconfig文件,我又不想在写一份,可以用该属性

"files":[xxx.ts,xxx.ts]指定被编译的文件列表

compilerOptions{} 编译器配置

target: 用来指定ts 编译后的Es版本,默认ES3,,可选值es3,es5,es6,es2015,es2016,es2017,es2018,es2019,es2020,esnext

lib[] 用来指定项目中要使用的库,一般不动他

module: 指定要使用的模块化规范,可选值:none commonjs amd system umd es6 es2015 es2020 exnest

outDir: 用来指定版以后文件所在的目录

outFile: 将代码合并成一个文件,设置outFile 后 所有的全局作用域中的代码会合并到同一个文件中。

allowJs: 是否对js文件进行编译,默认false

checkJs: 是否检查js文件语法

removeComments: 编译时是否去除注释

noEmit: 不生成编译后的文件

noEmitOnError: 当有错误时不生成编译文件

// 语法检查的属性

alwaysStrict: 严格模式,用来设置编译后的文件是否使用严格模式,默认false

noImplicitAny: 不允许使用隐式any

noImplicitThis: 不允许使用不明确类型this

strictNullChecks: 严格的检查空值,

strict: 所有严格模式的总开关,这个属性一定要写在最上面

*/

"compilerOptions": {

"module": "commonjs",

"target": "ES5",

"sourceMap": true,

"outDir": "./dist",

// "outFile": "./dist/app.js"

"allowJs": false,

"checkJs": false,

"removeComments": false,

"noEmit": false,

"noEmitOnError": false,

"strict": false,

"alwaysStrict": false,

"noImplicitAny": false,

"noImplicitThis": false,

"strictNullChecks": false

},

"exclude": [

"node_modules"

],

"include": ["./src/**/*"]

}

六、Webpack

1.命令行输入:npm init -y 对项目进行初始化。会自动生产package.json文件 2.安装wabpack所需要的依赖 npm i -D webpack webpack-cli typescript ts-loader 其中-D为开发环境,webpack-cli为webpack命令行工具,typescript 包,ts-loder为ts和webpack整合工具 根目录新建wabpack.config.js文件

/ 引入一个包

const path = require('path')

// webpack 中的所有的信息都应该写在module.exports中

module.exports = {

// 指定入口文件

entry:'./src/index.ts',

// 指定打包文件所在目录

output:{

// 指定打包文件的目录

path: path.resolve(__dirname,'dist'),

//打包后文件的名字

filename:"bundle.js"

},

//指定webpack打包时要使用的模块

module:{

// 指定要加载的规则

rules:[

{

// test 指定的时规则生效的文件

test: /\.ts$/,

// 要使用的loader

use: 'ts-loader',

// 要排除的文件

exclude: /node_modules/

}

]

}

}

3.新建tsconfig.json文件

{

"compilerOptions": {

"module": "ES2015",

"target": "ES2015",

"strict": true

}

}

4.在package.json文件中的scripts加入build:webpack属性用于打包

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack"

},

5.后续使用npm run bulid进行打包编译

命令行执行npm i -D html-webpack-plugin,帮助我们自动生成html文件 1.webpack.config.js 引入webpack-plugin

// 引入html插件

const HTMLWebpackPlugin = require('html-webpack-plugin')

//在module.exports中添加如下代码,template为自定义html,如过没有该属性,它会在编译时自动创建一个html

plugins:[

new HTMLWebpackPlugin({

// title: "这是自定义的title"

template:"./src/index.html"

})

]

}

2.Webpack开发服务器: npm i -D webpack-dev-server 安装完之后,在package.json的scripts属性下添加start:”webpack serve --open chrome.exe”

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"build": "webpack",

"start": "webpack serve --open chrome.exe"

},

使用npm run start进行编译,编译完成后自动打开谷歌浏览器 3.npm i -D clean-webpack-plugin ,每次在编译时都会先清空dist文件夹,保证每次都是最新的文件 安装完后,在webpack.config.js文件下引入: / 引入clean插件

const {CleanWebpackPlugin } = require('clean-webpack-plugin')

// 并在plugins下添加

plugins:[

new CleanWebpackPlugin(),...

]

4.引用模块编译报错,如使用import引入某个js 或ts,编译时会出错,需要在webpack.config.js加入如下配置

/ 用来设置引用模块

resolve:{

extensions:['.ts','.js']

}

Bable 解决兼容性问题,tsconfig可以设置es版本,它只是语法上的转换,bable可以兼容不同的浏览器, npm i -D@babel/core @babel/preset-env babel-loader core-js 安装完成后,打开webpack-config.js 在module.rules下use改为

//指定webpack打包时要使用的模块

module:{

// 指定要加载的规则

rules:[

{

// test 指定的时规则生效的文件

test: /\.ts$/,

// 要使用的loader

use: [{

// 指定加载器

"loader":"babel-loader",

// 设置bable

Option:{

// 设置预定义的环境

presets:[

[ // 指定环境的插件

"@babel/preset-env",

// 配置信息

{

// 要兼容的目标浏览器

targets: {

"chrome": "88",

"ie":"11"

},

// 指定corejs的版本

"corejs":"3",

// 使用corejs的方式,‘usage’表示按需加载

"useBuiltIns":'usage'

}]

]

}

},'ts-loader'], //它是由后向前执行,先将ts转换为js,在将js转换为浏览器兼容的js版本

// 要排除的文件

exclude: /node_modules/

}

]

},

Webpack 打包时不在最外层添加箭头函数,ie不支持箭头函数。

在webpack-config.js,在output下添加environment属性

output:{

// 指定打包文件的目录

path: path.resolve(__dirname,'dist'),

//打包后文件的名字

filename:"bundle.js",

// 告诉webpack 打包时不使用箭头函数

environment:{

arrowFunction: false

}

},

七、面向对象

面向对象是程序中一个非常重要的思想,它被很多同学理解成了一个比较难,比较深奥的问题,其实不然,面向对象很简单,简而言之,就是程序之中所有操作都需要通过对象来完成。 举例说明: 1.操作浏览器要使用window对象 2.操作网页要使用docurment对象 3.操作控制台要使用console对象 一切操作都需要对象,也就是所谓的面向对象,那么对象到底是什么呢? 这就要先说到程序是什么,计算机程序的本质就是对显示十五的抽象,抽象的反义词就是具体,比如,照片是对一个具体人的抽象,汽车模型是对具体汽车的抽象,程序也是对事物的抽象,在程序中我们可以表示一个人,一条狗,一把枪,一颗子弹等等所有事物,一个事物到了程序中就变成了一个对象。 在程序中,所有的对象都被分成了两个部分数据和功能,以人为例,人的姓名,性别,年龄,身高,体重等属于数据,人可以说话,走路,吃饭睡觉这些属于人的功能,数据在对象中被成为属性,而功能就被称为方法,所以简而言之,在程序中一切皆是对象。

1.类(class) 要想面向对象操作对象,首先要拥有对象,那么下一个问题就是如何创建对象,要创建对象,必须要先定义类,所谓的类可以理解为对象的模型,程序中可以根据类创建指定类型的对象,举例来说:可以通过person类来创建人的对象,通过Dog类可以创建狗的对象,通过Car类来创建汽车的对象,不同的类可以用来创建不同的对象。

/ 使用class关键字来定义一个类

/**

* 对象中主要包含了两个部分

* 属性

* 方法

*/

class Person{

/*

直接定义的属性是实例属性,需要通过对象实例去访问:

const per = new Person();

console.log(per.name)

使用static开头的属性是静态属性(类属性)

console.log(Person.age)

readonly 开头的属性,表示只读的属性,不能修改

*/

// 定义实例属性

name: string = '孙悟空';

// 在属性前使用static 关键字可以定义类属性(静态属性)

static age: number = 18;

// 定义方法

/**

* 如果方法以static开头,则方法就是类方法,可以直接通过类调用

*/

sayHello(){

console.log('hello 大家好!')

}

}

const per = new Person();

console.log(per.name)

console.log(Person.age)

per.sayHello()

2.构造函数和this

class Dog {

name:string;

age:number;

// constructor被称为构造函数

// 构造函数会在对象创建时调用

constructor(name:string,age:number){

console.log('构造函数执行了~~~')

//在实例方法中this就表示当前的实例,

// 在构造函数中当前对象就是当前新建的那个对象

console.log(this)

this.name=name

this.age=age

}

bark() {

// alert('汪汪汪')

// 在方法中可以通过this来表示当前调用方法的对象

console.log(this.name)

}

}

const dog1 = new Dog('小黑',19)

const dog2 = new Dog('小白',2)

console.log(dog1)

dog1.bark() // 小黑

dog2.bark() // 小白

3.继承和重写

class Animal {

name: string;

age: number;

constructor(name:string,age:number){

this.name=name;

this.age=age;

}

sayHello(){

console.log("嘎嘎嘎")

}

}

// 表示猫的类

class Cat extends Animal{

//

sayHello(){

console.log('喵喵喵')

}

}

/**

* Dogs extends Animal

* -此时,Animal被称为父类,Dog被称为子类

* - 使用继承后,子类将会拥有父类所有的方法和属性

* - 通过继承可以将多个类中共有的代码写在一个父类中,这样只需要写一次即可让所有子类都同时拥有父类的属性,

* -如果希望在子类中添加父类没有的属性或方法,直接加就行

* - 如果在子类中添加了和父类相同的方法,则子类方法会覆盖父类的方法

* 这种子类覆盖父类方法的形式,我们称为重写

*/

// 表示狗的类

class Dogs extends Animal{

run(){

console.log(this.name + "哈利波特骑着扫帚飞~")

}

sayHello(){

console.log('汪汪汪')

}

}

const cat = new Cat("小黑猫",4)

const dogs = new Dogs("小黑猫",4)

4.Supper

class Animal{

name: string

constructor(name:string){

this.name=name

}

sayHello(){

console.log('hahaha')

}

}

class Dog extends Animal {

age: number

constructor(name:string,age:number){

// 如果在子类中写了构造函数,在子类构造函数中必须调用父类构造函数supper()

super(name) // 调用父类的构造函数

this.age = age

}

sayHello() {

// 在类方法中,super就表示当前类的父类

super.sayHello()

}

}

5.抽象

/**

* 以abstract开头的类是抽象类,

* 抽象类和其他类区别不大,只是不能用来创建对象 new Animal,

* 它生下来就是给人当爸爸的,抽象类就是专门用来被继承的类

*

* 抽象类中可以添加抽象方法,

*/

abstract class Animal{

name: string

constructor(name:string){

this.name=name

}

// 定义一个抽象方法,以abstract开头,没有方法体

// 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写;

abstract sayHello():void;

}

class Dog extends Animal {

sayHello() {

console.log('汪汪汪')

}

}

class Cat extends Animal {

sayHello() {

console.log('喵喵喵')

}

}

6.接口

// 描述一个对象的类型

type myType = {

name: string,

age: number

}

const obj:myType ={

name: 'aaa',

age: 12

}

/**

* 接口用来定义一个类的结构,用来定义一个类中应该包含哪些属性和方法

* 同时接口可以当成类型声明去声明,

*/

interface myInterface {

name: string,

age: number

}

interface myInterface {

gender: string

}

const obj1:myInterface ={

name: 'aaa',

age: 12,

gender: '男'

}

/**

* 接口可以在定义类的时候去限制类的结构

* 接口中的所有的属性都不能有实际的值

* 接口只定义对象的接口,而不考虑实际值

* 在接口中所有的方法都是抽象方法

*/

interface myInter {

name: string;

sayHello():void;

}

/**

* 定义一个类时,可以使用类去实现一个接口

* 实现接口,就是使类满足接口的要求

*/

class MyClass implements myInter{

name: string;

constructor(name:string) {

this.name = name

}

sayHello(): void {

console.log('大家好')

}

}

7.属性的封装

// 定义一个表示人的 类

class Person {

// TS可以在属性前添加属性的修饰符

/**

* public 修饰的属性可以在任意位置访问(修改)默认值

* private 私有属性,私有属性只能在类内部进行访问(修改)

* - 可以通过类中添加方法,使得私有属性可以被外部访问

* protected 受保护的属性,只能在当前类和当前类的子类中访问(修改)

*/

private _name:string;

private _age:number;

constructor(name:string,age:number){

this._name=name;

this._age=age;

}

/**

*

* getter 用来读取属性

* setter 用来设置属性

* -它们被称为属性的存取器

*/

// 定义方法,用来获取name属性

// getName() {

// return this._name

// }

// // 定义方法,用来设置name属性

// setName(name:string) {

// return this._name = name

// }

// // 定义方法,用来获取name属性

// getAge() {

// return this._age

// }

// // 定义方法,用来设置name属性

// setAge(age:number) {

// if(age >= 0) {

// return this._age = age

// }

// }

// TS中设置getter方法的方式

// 用起来和属性一样 console.log(per.name)

get name(){

return this._name

}

// 用起来和属性一样 per.name = '猪八戒'

set name(name:string) {

this._name = name

}

}

const per = new Person('孙悟空', 8)

/**

* 限制属性是在对象中设置的,属性可以任意的被修改

* 属性可以任意被修改将会导致对象中的数据非常不安全

*/

// per._age = 38

// per.getName()

// per.setName('猪八戒')

console.log(per.name)

per.name = '猪八戒'

语法糖

class A{

num:number;

constructor(num:number){

this.num =num

}

}

可写成

class A{

constructor(public num:number){

}

}

8.泛型

// function fn(a:number):number{

// return a

// }

/**

* 在定义函数或是类时,如果遇到类型不明确就可以使用泛型

* T可以写其他字母都可以,它代表不明确类型,只有代码执行的时候,传进来什么类型就是什么类型

*/

function fn(a: T):T{

return a

}

// 可以直接调用具有泛型的函数

fn(10) // 不指定泛型,TS可以自动对类型进行推断

fn('10')

fn(false)

fn('hello') // 指定泛型,

// 泛型可以直接指定多个

function fn2(a:T,b:K):K{

return b

}

fn2(123,'344');

interface Inter {

length: number;

}

// T extends Inter 表示泛型T必须是Inter实现类(子类)

function fn3(a:T):number{

return a.length

}

fn3({length: 10})

class MyClass {

name: T;

constructor(name:T){

this.name = name

}

}

const mc = new MyClass('孙悟空')

const mc1 = new MyClass(123)

9.安装css 解析器 npm i -D less less-loader css-loader style-loader 在wabpace.config.js中 module下加入

{

test: /\.less$/,

use: [

"style-loader",

"css-loader",

"less-loader"

]

}

css兼容性处理: npm i -D postcss postcss-loader postcss-preset-env

{

test: /\.less$/,

use: [

"style-loader",

"css-loader",

// 引入postcss

{

loader: "postcss-loader",

options: {

postcssOptions:{

plugins: [

["postcss-perset-env",

{

browsers: 'last 2 versions' // 兼容两个最新版本的浏览器

}]

]

}

}

},

"less-loader"

]

}

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。