typescript

开发环境搭建

  1. 安装Node.js
  2. 使用npm全局安装typescript
    进入命令行,输入 npm i -g typescript
  3. 创建一个ts文件
  4. 使用tsc对ts文件进行编译
    • 进入命令行
    • 进入ts文件所在目录
    • 执行命令ts xxx.ts

1.TS的类型声明

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

/* 
{}用来指定对象中可以包含哪些属性
语法 {属性名:属性值}
在属性名后加上?表示属性是可选的 */ 
let a :{name:string,age?:number};
a = {name:"lili"};
********************************************************
// ### 01 定义对象结构
// [propName:string]:any 表示任意类型的属性
let b:{name:string, [propName:string]:any};
b = {name:"lili",age:18,gender:"女"}
********************************************************
/*  ### 02 定义函数结构
设置函数结构的类型声明语法:
(形参:类型,形参:类型...) => 返回值
*/
let c :(a:number, b:number) => number;
c = function(n1,n2):number {
    return n1+n2;
}
********************************************************
/*
### 03 数组的类型声明:
类型[]
Array<类型>
 */
let d : string[];
d = ["a","b","c"];

let e :Array<number>;
e = [1,2,3];
********************************************************
/* 
### 04 元组就是固定长度的数组
语法:[类型,类型,类型]
 */
let f :[string,number];
f = ["hello",123]
********************************************************
/* 
### 05 enum 枚举 
*/
enum Gender {
    Male,
    Female
}
let g :{name:string,gender:Gender};
g ={
    name:"lili",
    gender:Gender.Male // "male"
} 

&逻辑与

// &表示同时拥有两个参数
let h:{name:string} & {age:number};
h = {name:"lili",age:18}

类型的别名

//适用于类型特别复杂的情况,简化类型的使用
type myType = 1|2|3|4|5;
let i :myType;

2.TS的编译选项

配置tsconfig.json文件

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

    // ### 01 "include"用来指定哪些ts文件需要被编译
   "include":[
   "./src/**/*" // src任意目录下的任意文件
   ],
   //  ### 02 "exclude" 不需要被编译的文件目录,
   //  默认值:["node_modules","bower_components","jspm_packages"]
   "exclude":[
       "./src/hello/**/*"
   ],
    //  ### 03  "extends" 定义被继承的配置文件
   "extends":"",
    //  ### 04 "files" 指定被编译文件的列表,只有需要编译文件数量少时才会用到
   "files:[
       "core.ts",
       ...
   ],
    //  ### 04 "compilerOptions" (重点)
    // 编译选项是配置文件中非常重要也比较复杂的配置选项,包含多个子选项
   "compilerOptions":{
       "target":"es6", // 用来指定ts被编译为的ES版本
       "module":"es2015", // 指定要使用的模块化规范
       "lib":["dom"], // 指定项目中要使用的库,一般不需要设置
       "outDir":"./dist", // 指定编译后文件所在的目录
       "outFile":"./dist/app.js", // 将所有全局作用域中的代码合并到一个文件中,如果想要合并模块("module":"system")
       "allowJs":false, //是否对js文件进行编译。默认为false
       "checkJs":false, // 是否检查js代码是否符合语法规范,默认为false
       "removeComments":false, // 是否移除注释
       "noEmit":true, // 是否生成编译后的文件
       "noEmitOnError":true, // 当有错误时不生成编译后文件
       "strict":false, //所有严格检查的总开关
       "alwaysStrict":false, // 编译后的文件是否使用严格模式,默认为false
       "noImplicitAny":true, // 不允许隐式的any类型
       "noImplicitThis":true, // 不允许不明确类型的this
       "strictNullChecks":true, // 严格地检查空值
   }
}

在命令行输入tsc(或者tsc -w:监视所有文件)就可以实现ts编译了

3.使用webpack打包ts代码

  1. 对项目进行初始化 (生成package.json文件);
    npm init -y

  2. 安装webpack所需依赖;
    cnpm i -D webpack webpack-cli typescript ts-loader
    其他优化的依赖:
    cnpm i -D html-webpack-plugin——自动生成html文件,
    cnpm i -D webpack-dev-server——项目里面安装内置服务器,热刷新,
    cnpm i -D clean-webpack-plugin——生成新文件前清空dist文件夹,
    cnpm i -D @babel/core @babel/preset-env babel-loader core-js——生成不同版本文件,解决浏览器兼容性问题

  3. 编写webpack配置文件webpack.config.js;

// 引入一个包
const path = require("path");
// 引入html插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 引入clean插件
const {CleanWebpackPlugin} = require("clean-webpack-plugin");

// Webpack中的所有配置信息都应该写在module.exports中
module.exports = {
    entry:"./src/index.ts", // 指定入口文件
    // 指定打包文件所在目录
    output: {
        path:path.resolve(__dirname,"dist"), // 路径
        filename:"bundle.js" // 打包后文件的名字
        // 告诉webpack不使用箭头函数(兼容ie的情况)
        environment:{
        	arrowFunction:false
        }
    },
    // 指定webpack打包时要使用的模块
    module: {
        // 指定要加载的规则
        rules: [
            {
                test:/\.ts$/, //指定规则对哪些文件生效
                use:[
                	// 配置babel
                	{
                		// 指定加载器
                		loader:"babel-loader",
                		// 设置babel
                		options:{
                			// 设置预定义的环境
                			presets:[
	                			[
	                				// 指定环境的插件
	                				"@babel/preset-env",
	                				// 配置信息
	                				{
	                					// 要兼容的目标浏览器
	                					target:{
	                						"chrome":"58",
	                						"ie":"11"
	                					},
	                					// 指定corejs的版本
	                					"corejs":"3",
	                					// 使用core.js的方式 "usage"表示按需加载
	                					"useBuiltIns":"usage"
	                				}
	                			]
                			]
                		}		
                	},
                	'ts-loader', //要使用的loader,从后往前执行
                ]
                exclude:/node-modules/ //要排除的文件
            }
        ]
    },
    // 配置Webpack插件
    plugins:[
    	new CleanWebpackPlugin(),
    	new HTMLWebpackPlugin(options:{
    		// title:"这是一个自定义的title",
    		template:"./src/index.html", // 指定网页生成模板
    	}),
    ],
    // 用来设置引用模块
    resolve: {
    extensions:[".ts",".js"] // 指定哪些文件可以作为模块使用
    }
}
  1. 指定ts文件的编译规范 tsconfig.json;
  2. 往package.json文件中添加配置;
"scripts":{
	"build":"webpack",
	// 配置启动服务器
	"start":"webpack serve --open chrome.exe"	
}
  1. 执行编译命令;
    npm run build
  2. 启动服务器查看;
    npm start

4.面向对象简介

面向对象,简而言之就是程序之中所有的操作都需要通过对象来完成。

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

/*
类中主要包含了两个部分:
    属性
    方法
 */

class Person {

    /* 
        直接定义的属性是实例属性,需要通过对象的实例去访问;
            const per = new Person();
            per.name
        
        使用static开头的属性是静态属性(类属性),可以直接通过类去访问
            Person.age
    
    */


    // 定义属性(实例属性)
    name:string = "lili";
    // 在属性前使用static关键字可以定义类属性(静态属性)
    static age:number = 18;

    // 定义方法
    sayHello() {
        console.log("Hello!");
    }
    // 类方法
    static sayHello2() {
        console.log("Hello");
    }

}

const per = new Person();
console.log(per.name);
// 静态属性通过类来访问
console.log(Person.age);

per.sayHello();
Person.sayHello2();
  • 构造函数和this
class Dog{
    name: string;
    age: number;
    // constructor 被称为构造函数
    // 构造函数会在对象创建时调用
    constructor(name:string,age:number) {
        // 在实例方法中,this就表示当前的实例
        // 在构造函数中当前对象就是当前新建的那个对象
        // 可以通过this向新建的对象中添加属性
       this.name = name;
       this.age = age;  
    }
    bark() {
        // 在方法中可以通过this来表示当前调用方法的对象
        console.log(this.name);
    }
}

const dog1 = new Dog("小黑",4);
const dog2 = new Dog("小白",2);

dog1.bark();
  • 继承和super

// 定义一个animal类
class Animal {
    name: string;

    constructor(name:string) {
        this.name = name;
    }
    sayHello() {
        console.log("动物在叫");    
    }
}

/* 
    使用继承后,子类会拥有父类所有的方法和属性;
    通过继承可以将多个类中共有的代码写在一个父类中,避免代码的重复;
    子类可以对父类中的方法进行拓展和重写;
    子类中使用super关键字调用父类的方法;
*/

// 使Dog类继承Animal类
class Dog extends Animal{
    age:number
    constructor(name:string,age:number) {
        // 如果在子类中写了构造函数,在构造函数中必须对父类的构造函数进行调用
        super(name); // 调用父类的构造函数
        this.age = age;
    }
    // 子类独有的方法
    run() {
        console.log("I`m running");
    }
    sayHello() {
        // super表示当前类的父类
        super.sayHello();
        // console.log("汪汪!");
    }
}
// 使Cat类继承Animal类
class Cat extends Animal{
    sayHello() {
        console.log("喵喵!");
    }
}

const dog = new Dog("旺财",2);
const cat = new Cat("咪咪",3);
dog.run()
  • 抽象类
/* 
    以abstract开头的类是抽象类,
    抽象类是专门用来被继承的类,不能用来创建对象;
    抽象类中可以添加抽象方法;
*/
abstract class Animal {
    name: string;

    constructor(name:string) {
        this.name = name;
    }
    // 定义一个抽象方法
    // 抽象方法使用 abstract 开头,没有方法体
    // 抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
    abstract sayHello():void;
}
  • 接口

// 描述一个对象的类型
type myType = {
    name:string,
    age:number
};

/*  ### 01
    使用接口来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
    同时接口也可以当成类型声明去使用;

*/
interface myInterface {
    name:string,
    age:number;
}

const obj:myType = {
    name:"sss",
    age:11
};

/* ### 02 
    接口可以在定义类的时候去限制类的结构;
    接口中所有的属性都不能有实际的值,
    接口只定义对象的结构,而不考虑实际值,
    在接口中所有的方法都是抽象方法
*/

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

/* 
    定义类时,可以使类去实现一个接口,
    实现接口就是使类满足接口的要求
*/
class MyClass implements myInter {
    name: string;
    constructor(name:string) {
        this.name = name;
    }
    sayHello() {
        console.log("hi");
    }
}
  • 属性的封装
// 封装:不参与直接修改属性,让数据更安全

class Person {

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

    /* 
        public 修饰的属性可以在任意位置访问(修改)默认值;
        private 私有属性,只能在类内部进行访问(修改)
            通过在类中添加方法使得私有属性可以被外部访问
        protected 受保护的属性,只能在当前类及其子类中进行访问(修改0
    */

    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(value:string) {
        this._name = value;
    }

    getAge() {
        return this._age;
    }

    setAge(value:number) {
        if (value >= 0) {
            this._age = value;
        }
    } */

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

    get name() {
        return this._name;
    }
    set name(value) {
        this._name = value;
    }
    get age() {
        return this._age;
    }
    set age(value) {
        if (value >= 0) {
            this._age = value;
        }
    }
}

const per = new Person("lili",23);

// 外部获取
console.log(per.name);
per.age = -33;

***********************************************

class A {
    protected num:number;

    constructor(num:number) {
        this.num = num;
    }
}

class B extends A {
    test() {
        // 使子类可以拿到属性
        console.log(this.num);
    }
}

***********************************************

class C {
    // 可以直接将属性定义在构造函数中
    constructor(public name:string, public age:number) {

    }
}
  • 泛型
// function fn(a:number):number {
//     return a;
// }

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

function fn<T> (a:T) : T {
    return a;
}

// 可以直接调用具有泛型的函数
let result = fn(10); // 不指定泛型,TS可以自动对类型进行推断
let result2 = fn<string>("hello"); // 指定泛型

 *****************************************************
// 定义多个泛型
function fn2<T,K>(a:T,b:K):T {
    console.log(b);
    return a;
}

*****************************************************
// 限制泛型的范围
interface Inter {
    length :number;
}

//  T extends Inter 表示泛型T必须是Inter的实现类(子类)
function fn3<T extends Inter>(a:T):number {
    return a.length;
}
fn3( {length:10});

class MyClass<T> {
    name:T;
    constructor(name:T) {
        this.name = name;
    }
}
const mc = new MyClass<string>("lili");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛江清

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值