TypeScript 学习笔记 (2小时极速入门 TypeScript)

‘## 大纲

理论基础——开发环境——编译原理——工作流程——相关工具

基础类型学习

数字、布尔、字符串、数组、元组、联合、枚举、any、unknow、void、undefined、never

面向对象

泛型、class、interface、module、nameSpace(命名空间)、元编程meta-programming(装饰器)

了解TypeScript 工作流

安装typescript

npm install -g typescript

检测typescript是否安装

tsc -v

使用

tsc **.ts
node **.js

javascrip 命名来源
ECMA International(爱玛国际)负责维护版本, 所以又称ECMAScript,缩写为ES

npm init // 创建包管理文件
npm install --save-dev lite-server

可以在命令行中开启服务器,lite-server服务器会根据根目录下index文件自动部署在localhost:3000这个url上,部署在服务器上的好处是编译完成之后可以避免刷新页面就可以显示新的代码

TypeScript 基础

typescript的基本类型

// 基本类型
boolean string number array null undefined object
tuple enum void never any
// 高级类型
union 组合类型
Nullable 可空类型
Literal 预定义类型

Number

  • 数字类型
  • 可以表示整数、浮点数、也可表示正负数

String

  • “string” ‘string’ `string`

boolean

function add(a:number, b:number) {
	return a + b
}

数组Array

let array1:number[] = [1,2,3,4]
let array2:Array<number> = [1,2,3,4]
let array3 = [1,2,3,4]
let array4 = [1,"string"]
let array5:any[] = [1,"string",true]

元组Tupple
一个特殊的数组,是一个固定长度,固定类型的数组,存在一定bug

let array:[number, string] = [123,"hahaha"] // 固定长度,固定类型的数组
// array.push(3) 不报错
// array[2] = 3 报错

联合类型Union
一个变量可以同时支持多个不同类型,支持的类型中间用|分割

let union:string|number
union = 1
union = "1"
union = true // 报错
let union2: 1|2|3 // 不仅划定了数据类型,还确定了取值范围 也是字面量类型
union2 = 1
union2 = 4 // 报错
function merge(n1:number|string,n2:number|string|resultType:"as-number"|"as-string"){
	if(resultType == "as-string") {
		return n1.toString() + n2.toString()
	}
	if(typeof n1 == "string" || typeof n2 == "string") {
		return n1.toString() + n2.toString()
	}else {
		return n1 + n2
	}
}

文献类型Literal

let literal:1|"2"|true|[1,2,3]

枚举类型Enum

enum Color = {
	red,
	green,
	blue
}
let color = Color.green
console.log(color) // 1
enum Color2 = {
	red = 5,
	blue = 10,
	green = 1
}
enum Color3 = {
	red = "red",
	blue = "blue",
	green = 1
}
let color = Color3.blue
console.log(color) // blue

any

let randomValue:any = 666
randomValue = "666"
randomValue = true

unknow

void undefined never

// 函数没有任何返回 就是void类型
function printResult(){
	console.log("hahaha")
}
// 等价于
function printResult():void{
	console.log("hahaha")
}
// 函数永远执行不完,就是never,因为有throw,所以永远执行不到最后一个}
function throwError(message:string, errorCode: number) {
	throw{
		message,
		errorCode
	}
}
throwError("没有找到"404)

类型适配(类型断言) Type Assertions
用于各种类型的适配工作

let message: any;
message = "hello"
message.endsWith("o") // message还是any类型,所以不能使用字符串自有的endsWith方法,但是此时message其实已经是string类型了,通知typeScript进行类型适配的过程,就是Type Assertions

let ddd = (<string>message).endsWith("o")
let ddd2 = (message as string).endsWith("o")

函数类型

let log = function(message){
	console.log(message)
}
let log2 = (message) => console.log(message)
let log3 = (message:string, code?:number) => console.log(message,code)
let log3 = (message:string, code:number = 0																													) => console.log(message,code)

typeScript 面向对象

const person = {
	firstName: "四",
	lastName: "李",
	age: 14
}
console.log(person.age)
console.log(person.nickname) // 原生js不会报错,ts会报错

与javaScript 键值对不同,typeScript是key to type 键类型对

const person:object = {
	firstName: "四",
	lastName: "李",
	age: 14
}
console.log(person.age) // 报错,相当于声明了一个{},浏览器并不知道具体内部构造

Interface接口

let drawPoint = (x,y)=>{
	console.log({x,y})
}
let drawPoint = point=>{
	console.log({x:point.x,y:point.y})
}
drawPoint({x: 200,y: 30})
drawPoint({x: "ha",y: "he"})
// 使用
let drawPoint = (point:Point)=>{
	console.log({x:point.x,y:point.y})
}
interface Point{
	x: number;
	y: number;
}

高内聚 低耦合
功能相关的事务应该放在同一个集合中,形成一个模块——高内聚
模块又应该相互独立,不同模块之间保持低耦合

interface IPoint{
	x: number;
	y: number;
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
}
class point implements IPoint{
	x: number;
	y: number;
	drawPoint:()=>{
		console.log("x=",this.x,"y=",this.y)
	};
	getDistances:(p:IPoint)=>{
		return Math.pow(p.x-this.x,2) +  Math.pow(p.y-this.y,2)
	};
}
const point = new Point() //对象 Object  实例instance
point.x = 2
point.y = 3
point.drawPoint()

使用构造函数constructor进行初始赋值

interface IPoint{
	x: number;
	y: number;
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
}
class point implements IPoint{
	x: number;
	y: number;
	// 构造函数不可以重载
	constructor(x: number, y: number) {
		this.x = x;
		this.y = y
	}
	drawPoint:()=>{
		console.log("x=",this.x,"y=",this.y)
	};
	getDistances:(p:IPoint)=>{
		return Math.pow(p.x-this.x,2) +  Math.pow(p.y-this.y,2)
	};
}
const point = new Point(2,3)
point.drawPoint()

interface IPoint{
	// 当在构造函数中使用访问修饰符修饰参数的同时,constructor会自动为我们生成对应的成员变量,并为成员变量赋值,此时不可以使用缺省方法
	constructor(public x: number, public y: number) {
		// this.x = x;
		// this.y = y
	}
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
}

Access Modifier 访问修饰符
typeScript中有三个访问修饰符

public // 默认成员变量和成员方法都是public
private
protected
const point = new Point(20,30)
// 仍然可以通过访问对象来给x,y重新赋值
point.x = 30
point.y = 50

这种在对象外部直接访问成员变量,甚至重新赋值的方法是不安全的

interface IPoint{
	// x: number; // 私有的话和接口有冲突
	// y: number;
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
	getX:()=>number;
	getY:()=>number;
	setX:(value)=>void;
	setY:(value)=>void;
}
class point implements IPoint{
	constructor(private x: number, private y: number) {
		// this.x = x;
		// this.y = y
	}
	drawPoint:()=>{
		console.log("x=",this.x,"y=",this.y)
	};
	getDistances:(p:IPoint)=>{
		return Math.pow(p.getX()-this.x,2) +  Math.pow(p.getY()-this.y,2)
	};
	// 缓冲带,避免一些错误
	setX:(value:number)=>{
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.x = value
	};
	getX: ()=>{
		return this.x
	};
	setY:(value:number)=>{
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.y = value
	};
	getY: ()=>{
		return this.y
	}
}
const point = new Point(2,3)
point.setX(10)
point.drawPoint()

get set 懒人包,编译器版本至少设置为es5以上,设置方法为tes -t es5 + 文件名

tes -t es5 app.ts

好处: getter和setter不需要再写那么多代码,调用的时候也不需要像函数一样调用,只需要像属性一样使用就可以了,代码可以更整洁干净

interface IPoint{
	// x: number; // 私有的话和接口有冲突
	// y: number;
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
	// getX:()=>number;
	// getY:()=>number;
	X: number;
	Y: number;
	setX:(value)=>void;
	setY:(value)=>void;
}
class point implements IPoint{
	constructor(private x: number, private y: number) {
		// this.x = x;
		// this.y = y
	}
	drawPoint:()=>{
		console.log("x=",this.x,"y=",this.y)
	};
	getDistances:(p:IPoint)=>{
		return Math.pow(p.X-this.x,2) +  Math.pow(p.Y-this.y,2)
	};
	// 缓冲带,避免一些错误
	set X(value:number){
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.x = value
	};
	get X{
		return this.x
	};
	set Y(value:number){
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.y = value
	};
	get Y(){
		return this.y
	}
}
const point = new Point(2,3)
point.X = 10 // 赋值
console.log(point.X) // 取值

Module 模块
point.ts

// point.ts
interface IPoint{
	// x: number; // 私有的话和接口有冲突
	// y: number;
	drawPoint:()=>void;
	getDistances:(p:IPoint)=>number;
	// getX:()=>number;
	// getY:()=>number;
	X: number;
	Y: number;
	setX:(value)=>void;
	setY:(value)=>void;
}
export class point implements IPoint{
	constructor(private x: number, private y: number) {
		// this.x = x;
		// this.y = y
	}
	drawPoint:()=>{
		console.log("x=",this.x,"y=",this.y)
	};
	getDistances:(p:IPoint)=>{
		return Math.pow(p.X-this.x,2) +  Math.pow(p.Y-this.y,2)
	};
	// 缓冲带,避免一些错误
	set X(value:number){
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.x = value
	};
	get X{
		return this.x
	};
	set Y(value:number){
		if(value < 0) {
			throw new Error("value不能小于0")
		}
		this.y = value
	};
	get Y(){
		return this.y
	}
}

app.ts

import { Point } from './point' // 不需要加后缀
const point = new Point(2,3)
point.X = 10 // 赋值
console.log(point.X) // 取值

Generics 泛型
类型加尖括号这种形式就是泛型,相当于一个泛型模板

// let array1:number[] = [1,2,3,4]
// let array2:Array = [1,2,3,4]
let lastInAray = (arr: Array<number>) => {
	return arr[ arr.length - 1 ]
}
const l1 = lastInAray([1,2,3,4])
// const l2 = lastInAray(["a","b","c","d"]) 把类型修改为any也可以满足,但是输出的l2类型也是any

在函数参数前面写上表示动态类型泛型(约定俗称),可以把T传入参数类型的定义,用T动态的代替Array中的类型

// arr: Array & T[]
let lastInAray = <T>(arr: Array<T>) => {
	return arr[ arr.length - 1 ]
}
const l1 = lastInAray([1,2,3,4]) // 此时l1的类型是number
const l2 = lastInAray(["a","b","c","d"]) // 此时l2的类型是string

通过使用泛型,完美保持代码中类型的一致性

// 也可以明确指明泛型的类型,显示定义类型,提高安全性
const l2 = lastInAray<string>(["a","b","c","d"]) // 此时l2的类型是string
// 联合类型
const l3 = lastInAray<string|number>(["a","b","c","d"]) // 此时l3的类型是string|number的联合类型
let makeTuple = (x,y)=>[x,y]
// 多泛型使用
let makeTuple = <T, Y>(x:T,y: Y)=>[x,y]
const m1 = makeTuple(1,"a") // m1:(string|number)[]
const m2 = <Boolean,String>makeTuple(true,"a")

设置泛型默认类型

// 多泛型使用
let makeTuple = <T, Y = number>(x:T,y: Y)=>[x,y]
const m1 = makeTuple(1,"a") // m1:(string|number)[]
const m2 = <boolean,string>makeTuple(true,"a")

待扩展内容
类型别名、声明合并、接口合并、类型合并、class的继承与多态、模块、命名空间

你可能感兴趣的:(前端,菜鸡日记,typescript,javascript,前端)