TypeScript
TypeScript是JavaScript类型的升级版(是一个有静态类型的js升级版),它要编译成纯JavaScript才能运行。
Ts相较于Js的好处
- 在代码编写中就能发现一些潜在的问题,而js要运行时才能发现
- 在编写代码时,编辑器有更好的代码提示
- 代码语义更清楚,易懂
一、下载TypeScript
typescript是一个npm包,所以要通过npm i typescript
进行下载
下载完成之后就可以通过新建.ts
文件,来书写typescript的代码了
二、运行Ts文件
- 通过node运行:
- 环境:
- typescript
- node
- 执行某个ts文件:
tsc ts文件名
,这个方法他会生成一个js文件,然后在node 那个js文件
就可以运行了
- 环境:
- 通过ts-node运行
- 环境:
- typescript
- node
- ts-node(我们知道ts要编辑成js文件才能运行,下载这个包可以直接运行ts文件,就可以得到结果了)
- 执行某个ts文件:
ts-node ts文件名
- 环境:
- 运行整个项目
- 首先使用
tsc --init
生成一个名为tsconfig.json
配置文件 - 然后输入
tsc
他就会对整个项目进行tsc转换
- 首先使用
静态类型介绍
首先我们通过一个ts静态类型与js动态类型做比较的案例,来认识ts的静态类型
静态类型不仅能限制变量的类型,而且被赋予类型的变量还能获取类型上的方法,
例如:变量a的静态类型是number,a就可以通过a.number方法
的方式来调用number上的方法
//01.js
let a = 123
//js动态类型,所以没有类型限制
a = '123'
//01.ts
let a: number = 123
//正确
a = 345
//错误,因为变量a规定了变量的类型只能是数字类型。
a = '123'
基本类型
/**
* 原始数据类型
* 期中不在严格模式下原始数据类型是允许为null或undefined的
* */
const a:string='foobar'
const b:number=123
const c:boolean=true //false
const d:void=undefined
const e:null=null
const f:undefined=undefined
const g:symbol=Symbol()
const h:string|number=1
/**
* 对象类型
* */
//这里的对象不单指对象,可以是函数,数组,对象
const foo:object=function(){} //[] //{}
//这里的对象单指一个对象(注意要保持数量的一致,不能多写也不能少写)
const obj:{foo:number,bar:string}={foo:123,bar:'123'}
/**
* 数组类型
* */
//1.纯数字数组
const arr1:Array<number> =[1,2,3]
//2.纯数字数组
const arr2:number[]=[1,2,3]
//任意类型的数组
const arr3: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];
//案例--规定传入的参数类型只能是数字
function sum(...arg:number[]){
//求相加的和
return arg.reduce((prev,current)=>prev+current,0)
}
sum(1,2,3)
/**
* 元组类型--固定长度,固定类型
* */
const tupe:[number,string]=[18,'你好']
/**
* 枚举类型
* 枚举类型默认第一个为0,后面的元素都加1
* */
const enum PostState{
Draft,//0
Unpublished,//1
Published//2
}
const enum PostState2{
Draft=6,//6
Unpublished,//7
Published//8
}
//案例--如果一个返回对象中需要一个状态值,表示不同的状态,那就用枚举类型
const post = {
title:'hello',
status:PostState.Draft
}
/**
* 函数类型,规定函数的参数和返回值
* 在参数中加问号,代表可传可不传
* 默认值,和...都是es6的新语法
* */
function fun1(str:string,num?:number,test:number=10,...arg):string{
return str+num+test
}
console.log(fun1('1'))
console.log(fun1('1',1,2))
/**
* any:任意类型,即像js的隐式类型
* */
function stringIfy(value:any){
return JSON.stringify(value)
}
stringIfy('string')
stringIfy(100)
stringIfy(true)
/**
* 隐式类型推断
* 如果你没有声明,明确的类型,ts会根据你传的值进行隐式类型推断
* */
//案例1
let age=10 //在这个就把这个变量识别为number类型的变量
// age='123' //再传字符串进去就不对了--报错
//案列2
let afr //他为any类型
afr=123
afr='123'
afr=true
/**
* 断言--辅助ts来规定变量的类型
* */
var list1=[1,2,3,4]
const num1=list1.find(i=>i>0)
const num2=num1 as number
/**
* 接口,接口是用来对有结构的数据进行类型约束
* */
interface Post{
title:string,
content:string
subTitle?:string //可选成员 string|undefined
readonly summary:string //只读成员 在初始规定完了之后就不能再修改了
}
//约束传值的键和值的类型
const hello:Post={
title:'nihao',
content:'content',
summary:'只读'
}
// hello.summary='niaho' //报错--只读
//动态规定键和值的类型
interface Cache1{
[props:string]:string
}
var cache:Cache1={}
cache.foo='call'
// cache.add=0 报错,规定了动态类型
/**
* es6中的类
* */
class Person{
//对this的键进行类型注解
public name:string
private age:number //只能在本类中访问
protected readonly test:boolean //只能在本类和继承的子类中访问,后面的是一个只读属性,只能读不能修改
//对传入的值进行类型注解
constructor(name:string,age:number){
this.name=name
this.age=age
this.test=true
}
sayHi(msg:String):void{
console.log('i ame',this.name)
}
}
class Student extends Person{
//构造函数设置为静态的,所以只能通过静态方法createStudent创建
private constructor(name:string,age:number){
super(name,age)
console.log(this.test)
// console.log(this.age) //只能在Person中才能访问
}
static createStudent(name:string,age:number){
return new Student(name,age)
}
}
var person=new Person('赵佳乐',22)
console.log(person.name)
// console.log(person.age) //报错--private只能在类内部访问
//通过静态方法创建对象
var student=Student.createStudent('111',343)
console.log(student)
抽象类
//局部作用域
export{}
//抽象类--(抽象类只能被继承不能创建实例)
abstract class Animanl{
eat(food:string):void{
console.log('吃吃吃~',food)
}
//抽象方法(不用写方法体),当父类有抽象方法那子类就要实现这个方法
abstract run(distance:number):void
}
class Dog extends Animanl{
run(distance: number): void {
console.log('四肢爬行,速度:',distance)
}
}
//生成实例之后,他有父级的方法和自己生成的方法
const d=new Dog()
d.eat('骨头')
d.run(100)
泛型
export{}//局部作用域
//泛型,就是指把定义是不能明确的类型变成一个参数,再使用时再去传递
//创建一个数组,可能是一个纯数字的数据,也可能是一个字符串数组
//传统的方式要用两种函数来规定
function createArrayNumber(length:number,value:number):number[]{
const arr=Array<number>(length).fill(value)
return arr
}
function createArrayString(length:number,value:string):string[]{
const arr=Array<string>(length).fill(value)
return arr
}
//泛型函数
function createArray<T>(length:number,value:T):T[]{
const arr=Array<T>(length).fill(value)
return arr
}
const arr=createArray<string>(3,'000')
类型声明
export{}//局部作用域
/**
* 我们在npm导入一些模块的时候,如果没有类型声明?
* 1.可以手动的通过declare语法进行类型声明
* 2.大部分模块都可以通过下载@types/包名进行解决
* */
//1.给lodash的camelCase函数(对输入的字符串进行驼峰式命名)进行手动的类型声明
declare function camelCase(input:string):string