TypeScript学习笔记

TypeScript

TS是一门基于Javascript之上的编程语言,重点解决Javascript类型系统的问题。
大大提高代码的可靠程度。

强类型与弱类型(类型安全)

强类型:语言层面限制了实参类型必须与形参类型相同
强类型有更强的语言类型约束,弱类型几乎没有什么约束
强类型语言不允许任意的隐式类型转换
弱类型语言允许任意的隐式类型转换
class Main {
	static void foo(int num) {
		System.out.printIn(num)
	}
	public static void main(String[] args){
		Main.foo(100)
		Main.foo('100')
		Main.foo(Integer.parseInt('100'))
	}
}

静态类型与动态类型(类型检查)

静态类型语言:一个变量声明时它的类型就是明确的,而且声明过后变量的类型不允许修改
动态类型:运行时才能确定变量类型,而且变量类型可以发生明显的变化
JS是标准的动态类型语言
![编程语言,强弱静动语言区分]

在这里插入图片描述

Js自有的类型系统的问题

**弱类型语言的问题**
缺失了类型系统的可靠性,早前js的应用比较简单,
js没有编译环节,大规模应用下变成了短板
const obj = {}
obj.foo()//运行报错
//必须到运行阶段才发现错误
setTimeout(()=>{
	obj.foo()
},1000000)
//类型不明确,函数功能发生改变
function sum(a, b){
	return a + b
}
console.log(sum(10,20))
console.log(sum(10,'20'))
//对对象索引器的使用不正确
const obj1 = {}
obj1[true] = 1000
console.log(obj1['true'])//1000

强类型语言的优势
1、错误更早的暴露
2、代码更加智能,编码更加准确
3、重构代码更牢靠
4、减少一些不必要的类型判断

function render(el) {
	el.className = contain'
	console.log(el)
}

const util = {
	aaa:() => {
		console.log('util')
	}
}

Flow静态类型检查方案

Flow js的静态类型检查器,vue和react均有使用
通过添加一些类型注解的范式来标记变量类型

类型注解
function sum(a:number, b:number){
	return a + b
}
运行之前可以通过babel和官方提供的工具在运行前进行注解
yarn init
初始化package.json管理项目依赖

安装开发依赖
yarn add flow-bin

安装flow配置
yarn flow init 
移除类型注解
安装官方使用的移除注解的方法
yarn add flow-remove-types
安装完成后使用这个模块提供的工具去自动移除类型注解
指定转换过后的目录文件
yarn flow-remove-types . -d dist

//使用babel完成注解
core是babel的核心插件,cl工具命令行使用babel命令完成编译,flow
是转换类型注解的一个插件
yarn add @babel/core @babel/cli @babel/preset-flow -dev
新建.babelrc文件
{
    "presets":["@babel/preset-flow"]
}

yarn babel src -d dist
//将src下的目录文件全部编译到dist文件夹下
flow开发工具Vscode
Flow Language Support

```typescript
//添加flow标记,关闭vscode语法校验 file - preferences- settings - 搜素 javascript validate-取消勾选
//@flow

function sum(a:number, b:number){
    return a + b
}
console.log(sum(100, 100))
console.log(sum(100, '100'))

/**
 * 类型推断
 * 
 * @flow
 */
function square(n:number){
	return n * n
}
square('100')
//变量类型注解
let num:number = 100
num = '100'
//返回值类型注解
function foo():number{
    // return 100
    return '100'
} 
//如果没有返回值
function foo():void{
    
} 
flow类型推断
function square(n){
	return n * n
}
square('100')

flow支持哪些类型,以及高级用法()

//原始数据类型
const a:string= 'aaqq'
const b:number= Infinity
const c:boolean= true
const d:null= null
const e:void= undefined
const f:symbol= Symbol()

//数组类型
const arr1 : Array<number> = [1, 2, 3]
const arr2 : number[] = [1, 2, 3]
//固定长度的数组
const foo1 [string, number] = ['foo',100]//语言组

//对象类型
const obj1:{foo:string,bar:number} = {foo:'aaaa',bar:100}
//添加个问号,代表可有可无
const obj2:{foo?:string,bar:number} = {bar:100}
//类型限制
const obj3:{[string]:string} = {}
obj3.key1 = 'a1'
obj3.key2 = 'a2'
//函数的类型限制,对参数的参数类型和返回值类型进行限制
function foo(callback:(string,number)=>void){
	callback('aas',100)
}
foo(function(str,n){
	
})
//特殊类型
//字面量类型
const obj:'foo'= 'foo'
const type:'success' | 'error' | 'danger' = 'success'
const data:  string | number = 100/'aa'
type StringOrNumber = string | number 
const StringOrNumber  = 100/'aa'
//maybe类型
const gender : ?number = number /null / undefined

//任意类型 Mixed/Any
//强类型,需要做类型判断
function passMixed(val:mixed){
	if(typeof  val === string){
		return val.substring(1)
	}else{
		return val*val
	}
}
passMixed(string/Symbol/null / undefined/number/boolean)
function passAny(val:any){
	//Any是弱类型语言,不需要声明变量类型
	return val.substring(1)
	return val*val
}
passMixed(string/Symbol/null / undefined/number/boolean)

TS语言规范与基本应用

ts的概述

是一门基于js上的编程语言,是js的扩展集
ts= js + es6 + 类型系统
最终编译成js,任何js环境都支持ts
功能更加强大,生态更加健全完善,尤其是开发工具
缺点:
1、相对于js多了很多概念,增加了学习成本、但是可以用js语法使用,渐进式
2、周期比较短的项目,不适合,长周期维护的大型项目可以使用

ts 入门安装

安装ts  : yarn add typescript
运行: yarn tsc .ts可以针对某个文件进行编译
对整个项目进行编译需要重新配置
yarn tsc --init 生成了 tsconfig.json
放开下面三个
"sourceMap": true, 调试使用
"outDir": "dist",   输出
"rootDir": "src",  源代码所在的文件夹

ts 原始数据类型

const str: string = '2wqq'
const num:number = 100//Nan Infinity
const bool:boolean = true
const nu:null = null
const un:void = undefined
const un1:undefined = undefined
const s:symbol = Symbol()//报错去配置文件中修改  target:es2015

使用中文错误消息

yarn tsc --locale zh-CN

作用域的问题

const str = '1121'//因为str在其他文件里已经声明了,已经是全局变量了
//作用域问题
(function(){
	const a = 123
})()
或者用export导出,确保跟其他示例的变量没有冲突
对象类型
const foo:object= function(){}//[] {}
const obj:{foo:string, bar:number} = {foo:'21q', bar:121}
数组类型
const arr1:Array<number> = [1,2,3]
const arr2:number[] = [1,2,3]
function sum(...args:number[]){
	return args.reduce((pre, current)=> pre+current,0)
}
sum(arr1)
//元组类型:明确元素数量以及元素类型的数组
const tuple:[number,string] = [100,'obj']
const age1 = tuple[0]
const name1 = tuple[1]
const [age2,name2] = tuple 
//枚举类型

类 Classes

描述一类具体事物的抽象特征
用来描述一类具体对象的抽象成员
ES6之前,js都是通过函数+原型模拟实现类
类的属性必须在使用前去声明,为了给属性做些类型的标注
ES6开始,js有专门的class
ts增强了class的相关语法

export {}
class Person{
	name:string
	age:number
	constructor(name:string, age:number){
		this.name = name
		this.age = age
	}
	sayHi(msg:string):void{
		console.log(`I am a ${this.name},${msg}`)
	}
}

访问修饰符

控制可访问级别

export {}
class Person{
	public name:string//默认public 公共参数
	private age:number//private表示私有的修饰符,外界不可被访问 
	protected gender:boolean//受保护的修饰符,可以在子类里被访问
	constructor(name:string, age:number, gender:boolean){
		this.name = name
		this.age = age
	}
	sayHi(msg:string):void{
		console.log(`I am a ${this.name},${msg}`)
	}
}
class student extends Person{
	//构造器默认的也是public,如果设置了private,可以
	private constructor (name:string, age:number){
		super(name, age)//继承父类的参数
		console.log(this.gender)
	}
	static create (name:string, age:number){
		return new Student(name, age)
	}
}
const per = new Person('Tony', 21,true)
console.log(per.name)
const jack = student.create('Tony', 21)
//console.log(per.age)//报错
//console.log(per.gender)//报错,不能被访问,在子类里可以被访问

只读属性

export {}
class Person{
	public name:string
	private age:number
	protected readonly gender:boolean
	constructor(name:string, age:number){
		this.name = name
		this.age = age
		this.gender = true
	}
	sayHi(msg:string):void{
		console.log(`I am a ${this.name},${msg}`)
	}
}
const student = new Person('Joy', 33)
console.log(student.name)
//student.gender //报错

类和接口interface

不同的类之前有相同的属性,可以使用接口去抽象
类和接口的区别:接口中只声明成员方法,不做实现;类声明并实现方法。

export {}
interface Eat{
	eat(food:string):void
}
interface Run{
	run(distance:number):void
}
class Person implements Eat, Run{
	eat(food:string):void{
		console.log(`${food}`)
	}
	run (distance:number):void{
		console.log(`${distance}`)
	}
}
class Animal implements Eat, Run{
	eat(food:string):void{
		console.log(`${food}`)
	}
	run (distance:number):void{
		console.log(`${distance}`)
	}
}

抽象类

和接口有点类似,可以用来约束子类中拥有某些成员
但是接口不能实现,只能声明
一旦声明为抽象类,只能被继承

abstract class Animal{
	eat(food:string):void{
		console.log(`${food}`)
	}
	abstract run (distance:number):void//抽象方法
}
class Dog extends Animal{
	run (distance:number):void{
		console.log(`${distance}`)
	}
}
class dog = new Dog()
dog.eat('121')
dog.run(200)

泛型

在声明函数时不具体指明函数的类型,在使用时确定参数类型

export {}
function createNumberArray(length:number, value:number):number[]{
	const arr = Array[number](length).fill(value)
}
const ar = createNumberArray(3, 100)
//[100 100, 100]
function createStringArray(length:number, value:string):string[]{
	const arr = Array[string](length).fill(value)
}//T代表泛型不明确的数据类型
function createArray<T>(length:number, value:T):T[]{
	const arr = Array<T>(length).fill(value)
}
const ar1 = createArray<number>(3, 100)
console.log(ar1)
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值