TypeScript

入门

介绍:基于JS衍生,JS的超集,为限制JS的动态类型,TS为静态类型,减少项目BUG和后期维护成本

安装node.js【去官网】,安装TypeScript编译器【安装node后,命令行去全局安装TS编译器】

npm i typescript -g

命令行工具,进入ts文件目录,输入…即可将ts转js,默认编译为es3,可通过配置编译器es3~es12+

tsc 文件名.ts
变量定义
# 基本定义
let str: string = ''

let num: number
num = 18


# 简写形式,声明和赋值同时进行可以简写,默认第一次的类型
let arr = []

#声明类型,但是不会赋值
let arr: []

# js项目动态类型易出bug的地方,参数没有类型限制
# 参数类型限制,返回值类型限制
function sum(n1: number, n2: number) :number{
  return n1 + n2
}

# 限制变量在两个值之间选择,以此类推
let str : 'str1' | 'str2'

# 限制变量的类型,只能在两个类型之间选择,以此类推
let str : number | srring

# any 表示任意类型,声明不指定默认为any,可以赋值给其他已定义类型的变量
let str: any
let sty

# unknown 表示未知的类型,不可以赋值给其他已定义类型的变量,推荐使用unknown代替any
let str: unknown
sty = 18
sty = 'str'

# 类型断言,可配合unknown使用,告知解析器变量的实际类型
let num: number
num = str as number
num = <number>str

# void 表示空,在函数返回值中,限制返回值为undefined、null或者无返回值
function fun(): void{ return undefined }

# never 在函数中,表示没有返回值,如用于代码报错
function fun(): never{ }
声明对象
# 声明对象,obj对象的赋值1、name必须赋值;2、age?表示可以不写;3、有且仅有name和age【可不写】
let obj: {name: string, age?: number}
obj = {name: '名字'}

# 上一种写法限制了属性的数量和属性值的类型
# obj对象的赋值1、name必须赋值;2、多个任意属性名,任意类型属性值
let obj: {nzme :string, [otherName: string]: any}
obj = {name: '名字', age: 18, gender: '男'}
声明函数
# 声明函数对象的参数类型、数量和返回值的类型,给函数对象赋值的时候就可省略声明,但是要确保赋值要和声明对应
let fun: (num1: number, num2: number) => number
fun = function (n1, n2) return n1+n2 
声明数组
# 声明string类型数组,数组存放的值只能是string类型的
let arr: string[]

# 声明number类型的数组
let arr: Array<number>

# 【元祖】:固定长度的数组,性能更好
let tup: [string, number]
tup = ['str', 18]
enum枚举【TS新增】
# enum使用场景:性别等属性的赋值,属性值具有数量少,值固定的特点
enum Gender{
	Male = 0,
	Famale = 1
}

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

fun = {
	name: '名字',
	gender: Gender.Male
}
type类型别名【TS新增】
# type使用场景:类似于封装,简化代码
let num1 = 1 | 2 | 3 | 4
let num2 = 1 | 2 | 3 | 4
	||
	||
type myType = 1 | 2 | 3 | 4
let num1 = myType
let num2 = myType
类型例子描述
number1, -33, 2.5任意数字
string‘hi’, “hi”任意字符串
booleantrue、false布尔值true或false
字面量其本身限制变量的值就是该字面量的值
any*任意类型
unknown*类型安全的any
void空值(undefined)没有值(或undefined)
never没有值不能是任何值
object{ name: ‘孙悟空’ }任意的JS对象
array[ 1, 2, 3 ]任意JS数组
tuple[ 4, 5 ]元素,TS新增类型,固定长度数组
enumenum { A, B }枚举,TS中新增类型

编译

监视单文

​ 控制台 —— 当前目录下 ——【 tsc 文件名.ts

监视多文件

​ 新建【tsconfig.json】文件

​ 【tsc】编译所有文件,【tsc -w 】监视所有文件

配置【tsconfig.json】
  • 常规属性
{
	// 定义被编译文件所在的目录;【**】表示任意目录,【*】表示任意文件
	"include":["src/**/*", "tests/**/*"],
	
	// 定义需要排除在外的目录
	"exclude": ["./src/module/**/*"],
	
	// 定义被继承的配置
	"extends": "./configs/base",
	
	// 指定被编译文件的列表,编译的文件少时才会使用
	"files": [ "core.ts", "sys.ts" ],
	
	// 指定各种编译规范和编译模式
	compilerOptions: {
		
		// 设置ts编译js的目标版本 es2015 == es6,为了兼容可以编译es5
		"target": "ES6",
		
		// 设置编译后代码使用的模块化系统
		"module": "CommonJS",
		
		// 指定代码运行时所包含的库(宿主环境),一般不写这不配置,ts编译器默认采用内置的
		"lib": ["ES6", "DOM"],
		
		// 【outDir】 指定编译后文件的存放目录
		// 【outFile】 合并编译后的js文件,指定名称
		// 使用模块,指定【'module': 'system' | 'None' | 'AMD'】才能使用,二者结合打包工具使用
		"outDir": "dist",
    	"outFile": "dist/xx.js",
    	
    	// 【allowJs】是否编译js文件,【checkJs】是否检查js文件语法规范,默认都为flase,搭配使用
    	"allowJs": false,
    	"checkJs": false,
    	
    	// 是否删除编译后文件的注释,默认false
    	"removeComments": true,
    	
    	// 不生成编译后的文件,一般做ts语法检查时使用
    	"noEmit": false,
    	
    	// ts存在错误,不进行编译
    	"noEmitOnError": true
	}
}
  • 常用语法检查属性
{
	// 指定各种编译规范和编译模式
	compilerOptions: {
	
		//所有严格检查的总开关,开启之后,下方的严格检查自动开启,建议开启,减少项目后期可能出现的bug
		"strict" : true
		
        //用来设置编译后的文件是否使用严格模式,默认false
        "alwaysStrict" : true,

		//不允许隐式的any类型
		"noImplicitAny " : true,
		
		//不允许不明确类型的this,如普通函数中的【this】
		"noImplicitThis" : true,
		
		//严格的检查空值
		"strictNullChecks" : true,
		
    }
}
  • 非常用语法检查属性
    • strictBindCallApply:严格检查bind、call和apply的参数列表
    • strictFunctionTypes:严格检查函数的类型
    • strictNullChecks:严格的空值检查
    • strictPropertyInitialization:严格检查属性是否初始化
    • noFallthroughCasesInSwitch:检查switch语句包含正确的break
    • noImplicitReturns:检查函数没有隐式的返回值
    • noUnusedLocals:检查未使用的局部变量
    • noUnusedParameters:检查未使用的参数
    • allowUnreachableCode:检查不可达代码
    • noEmitOnError:有错误的情况下不进行编译

结合webpack

初始化【package.json】,管理项目

npm init -y

安装Webpack、TypeScript相关库

cnpm i -D
webpack webpack-cli webpack-dev-server typescript ts-loader clean-webpack-plugin
@babel/core @babel/preset-env babel-loader core-js
  • webpack:构建工具webpack

  • webpack-cli:webpack的命令行工具

  • webpack-dev-server:webpack的开发服务器

  • typescript:ts编译器

  • ts-loader:ts加载器,用于在webpack中编译ts文件

  • html-webpack-plugin:webpack中html插件,用来自动创建html文件

  • clean-webpack-plugin:webpack中的清除插件,每次构建都会先清除目录

  • @babel/core:babel的核心工具

  • @babel/preset-env:babel的预定义环境

  • @babel-loader:babel在webpack中的加载器

  • core-js:core-js用来使老版本的浏览器支持新版ES语法

新建【tsconfig.json】


新建【webpack.config.js】


修改【package.json】

{
	"script":{
		"build": "webpack"
	}
}

新建【babel】


面向对象

介绍:js将程序抽象成一个对象,这个对象又包含多个小对象,程序之中所有的操作都需要通过对象来完成,一切操作都要通过对象,也就是所谓的面向对象

  • 操作浏览器要使用window对象
  • 操作网页要使用document对象

在程序中所有的对象都被分成了两个部分:数据和功能

以人为例,人的姓名、性别、年龄、身高、体重等属于数据,人可以说话、走路、吃饭、睡觉这些属于人的功能

面向对象和面向过程

  • 面向对象可以看做是对象的封装【模块化】,将对象相关的方法和属性写入类中,不同的类为单独的TS文件,最后将所有类引入到【控制器类】中,项目越大,后期效果越好
  • 面向过程是对程序的每一步进行操作,将所有方法写到流程中,项目较小时可以使用
类 Class

对象:原对象和自定义对象。要想对对象进行各种操作,那就得赋予它各种属性,让它具备完成操作的能力

如何创建一个能完成各种操作的对象,要创建对象,必须要先定义类

类(class):对象的模型,程序中根据这个对象的模型,创建指定类型的对象,不同的模型创建不同的对象

  • 定义类

    class Person{ }
    
  • 使用类实例化对象

    const person = new Person
    
类的属性和方法
  • 实例属性、静态属性(类属性static),实例属性通过实例对象访问,静态属性通过对象访问
  • 例属性的值可以通过实例来修改,如果被【readonly】修饰,只可读
  • 类中的属性存在自动类型判断
  • 类中的方法也是如此,实例方法、静态方法、static修饰、readonly修饰、自动类型判断
class Person{
    name: string = '孙悟空'
    static age: number =18
    readonly gender: string = '男'
    height = 168
    
    eat(){ }
}

let per = new Person()

per.name === '孙悟空'
Person.age === 18
类的构造函数 Constructor

【constructor】类实例化的时候都会被调用,用于实例不同的对象,

class Person{
    name: string;
    age: number;

    constructor(name: string, age: number){
        this.name = name;
        this.age = age;
    }

    sayHello(){
        console.log this.name 
    }
}

const person1 = new Person('孙悟空', 18);
const person2 = new Person('猪八戒', 18);
类的继承 Extends

不同的类之间,可能会存在相同的属性,当相同属性较多时可以封装成父类,子类通过继承获取父类的属性

class Animal{
    name: string;

    constructor(name: string){
        this.name = name;
    }

    run(){ console.log('父类中的run方法!') }
}

class Dog extends Animal{
    bark() { console.log(`子类中的bark方法`) }
    run() { console.log(`子类中的run方法,会重写父类中的run方法!`) }
}

const dog = new Dog('旺财');
类的父类 Super

super在子类中,表示当前的父类

class Animal{
    name: string;
    constructor(name: string){
        this.name = name;
    }
}

class Dog extends Animal{
	constructor(name: string, age: number) {
		//子类中写了构造函数,构造函数中必须调用super(),否则父类的构造函数会被重写,继承失败
		super(name); 
		this.age = age;
	}
}

const dog = new Dog('旺财', 3);
类的属性修饰符
  • public(默认值),可以在父类、子类、对象中修改
  • private ,私有属性,可以在父类中修改
    • 在JS中,对象可以直接修改父类属性的值,这使得数据的安全性大大降低。属性设置private修饰,只能通过调用父类中的方法,去修改父类属性的值,属性的修改和读取由父类的方法控制,称为数据的存取器
    • 使用场景:当该属性的容易被修改错或是对计算要求比较高或是比较重要时,可在存取器的set()设置判断
  • protected ,受保护的属性,可以在父类、子类中修改
class test(){
	name: string
	constructor(name:string){ }
}

简写

class test(){
	constructor(public name:string){ }
}
抽象类 Abstract

抽象类是专门用来被其他类所继承的类,它只能被其他类所继承不能用来创建实例

abstract开头的方法叫做抽象方法,抽象方法没有方法体,只能定义在抽象类中,继承抽象类时抽象方法必须要实现

abstract class Animal{
    abstract run(): void;
    bark(){
        console.log('');
    }
}

class Dog extends Animals{
    run(){
        console.log('');
    }
}
接口 Interface

接口的作用类似于抽象类,不同点在于接口中的所有方法和属性都是没有实值的,接口中的所有方法都是抽象方法

接口主要负责定义一个类的结构,接口可以去限制一个对象的接口,对象只有包含接口中定义的所有属性和方法时才能匹配接口

interface Person{
    name: string;
    sayHello():void;
}

function fn(per: Person){
    per.sayHello();
}

fn({
	name:'孙悟空', 
	sayHello() { console.log( this.name ) }
});

让一个类去实现接口,类中要包括接口中的所有属性

interface Person{
    name: string;
    sayHello():void;
}

class Student implements Person{

    constructor(public name: string) { }

    sayHello() { console.log( this.name ) }
}
泛型 Generic

定义一个函数或类时,有些情况下无法确定其中要使用的具体类型(返回值、参数、属性的类型不能确定),此时泛型便能够发挥作用

  • 使用泛型之前,通过【any】,会关闭TS语法检查

    function test(arg: any): any{
    	return arg
    }
    
  • 使用泛型之后,【<>】中为任意字母

    function test<T, K>(a: T, b: K): K{
        return b
    }
    
    //不指定泛型,TS会自行推断,个别情况无法推断
    test(10, "hello")
    
    //指定泛型,推荐
    test<number, string>(10, "hello");
    
  • 在类中使用

    class test<T>{
        prop: T
    
        constructor(prop: T){
            this.prop = prop
        }
    }
    
    const test1 = new test<string> ( name: '孙悟空');
    
  • 对泛型范围进行约束,表示泛型T必须是MyInter的子类,test中的a对象实现,必须具有length属性

    interface MyInter{
        length: number
    }
    
    function test<T extends MyInter>(a: T): number{
        return a.length
    }
    
类型断言

在TS中,【!】表示对一个变量断言其非空,【as】用来限制child的类型,存在类型断言时【!】可不写

head : HTMLElement

test() { this.head = document.querySelector( selectors: '#box')! as HTMLElement }

练习

  • 纸上得来终觉浅,做一个TS项目实战,做一下笔记,巩固知识

其他

  • js开启严格模式,可以在代码首行添加【“use strict”】,性能更好,一般不单独开启,采用工具批量添加,js引入模块时,该文件自动开启严格模式

  • 【webpack.config.js】执行【loader】的顺序是从数组的下往上执行

  • 编译流程:编译执行——TS文件——tsloder(转JS)——bable(转ES5)

  • 【webpack】打包会自带一个箭头函数,不经过bable的编译,编辑【webpack.config.js】

    {
    	module.exports = {
    		output: {
    			enviroument:{ arrowFunction: false }
    		}
    	}
    }
    
  • 在webstorm中,【cnpm i】安装依赖,是镜像服务器提供的文件,文件相对较多,下载完会有点乱,网络好推荐用【npm i】,VS中推荐【cnpm i】,速度快

  • CSS3在低版本浏览器中不兼容,【webpack.json】通过【postcss postcss-loader postcss-preset-env】,【loader】处理顺序从下到上

    {
        test: /.less$/,
        use: [
            //将CSS引入项目,加载CSS,postcss处理CSS3兼容,less转css
            "style-loader",
            "css-loader",
            {
                loader: "postcss-loader",
                options: {
                    postcssOptions : {
                        plugins: [
                            [
                                "postcss-preset-env",
                                {  browsers: 'last 2 versions' }
                            ]
                        ]
                    }
                }
            },
            "less-loader"
        }
    }
    
  • 【document.querySelectorAll】能获取所有元素,但是个数限制第一次获取的数量

    【document.getElement】则不会

  • 事件绑定的【this】指向,【.bind(this)】可以将函数的【this】指向改为原函数,而不是调用者

    const direction: KeyboardEvent;
    
    document.addEventListener( type: 'keydown', this.test.bind(this) );
    
    test(event: KeyboardEvent){
    	this.direction = event.key
    }
    
  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值