TypeScript官网
// 安装 Typescript
npm install -g typescript
//使用 tsc 全局命令
tsc -v // 查看 tsc 版本
tsc fileName.ts // 编译 ts 文件
动态类型&静态类型
强类型&弱类型
数字类型,包含小数、其他进制的数字
默认十进制,0b表示二进制,0o表示八进制,ox表示十六进制
let num1:number=666.88
let num2:number=0xf00d
let bigNum:bigint=100n
字符串
let color:string="blue"
布尔值
值只能是true或false,不能是0或1
let isDone:boolean=false
任何值,不做任何类型检查(不建议使用)
let anySure:any=4
anySure='五六七'
anySure='false'
表示不返回任何值。
一般是用在函数返回类型上,表示没有任何返回值的函数,一般可省略。
只能将它赋值为null或者undefined
function hello():void{
console.log('hello')
}
表示不存在的对象值。
使用null关键字定义原始类型,本身无意义。
null一般用来当值,而不是类型使用
null类型可以被赋值为null、undefined、any,其他值不能对其进行赋值
let nv:null=null
let nv1:null=undefined
let nv2:null=2 //报错
已经声明单位初始化的变量的值。
undefined和null是所有类型的子类型,也就是说他们可以赋值给任何类型的变量
undefined一般用来当值,而不是类型使用
undefined类型可以被赋值为null、undefined、any,其他值不能对其进行赋值
let nv:undefined=null
let nv1:undefined=undefined
let nv2:undefined=2 //报错
其他类型的子类型(包括null和undefined),表示不会出现的值
never类型只能赋值给自身,其他类型不能给其赋值,包括any类型
never类型一般出现在函数抛出异常Error存在无法正常结束(死循环)情况下
//返回never的函数
function err(message:string):never{
throw new Error(message)
}
//推断返回值类型为never
function fall(){
return error('Something failed')
}
//返回never函数无法正常结束
function infiniteLoop(){
while(true){
}
}
es6引入的原始数据类型,表示独一无二的值
symbol类型的变量一旦创建就不可变更,且不能为它设置属性
symbol一般是作为对象的属性
symbol类型的值是通过symbol构造函数进行创建的
let s1=Symbol('name') //Symbol()
console.log(s1) //Symbol(name)
console.log(s1.toString) //"Symbol(name)"
//symbol不可改变且唯一
let s2=Symbol()
let s3=Symbol()
console.log(s2==s3) //false
let s4=Symbol('age')
let s5=Symbol('age')
console.log(s4==s5) //false
//作为对象属性的键
let obj={
[s1]:'小明', //Symbol('name'):'小明'
[s2]:12
sex:'man'
}
symbol类型不能和其他类型进行计算会报错
let s1=Symbol('name')
console.log(s1+'我是symbol') //报错
symbol类型转换
let s1=Symbol('name')
console.log(String(s1)) //'Symbol('name')'
console.log(Boolean(s1)) //true
console.log(Number(s1)) //报错
联合类型表示取值可以为多种类型
let a:string|number
a='123'
a=123
//判断类型
function add(x:number|string):number{
if(typeof x==='string'){
//如果是字符串类型
}else{
//如果是数字类型
}
}
手动指定一个值的类型
语法规则:
function add(x:number|string):number{
//转换成联合类型中不存在的类型会报错
const str=input as string //告诉ts 我更了解这个类型,就可以使用这个类型的全部方法
}
function getLength(a:number|string):number{
//if(a as string).length(){
if(a).length){
return (a).length
}else{
return a.toString().length
}
}
let list:Array=[1,2,3]; let arrOfNum:number[]=[1,2,3]; interface User{ name:string } const join={name="john"} const jack={name="jack"} //类数组 function test(){ // arguments 属于IArguments类型 console.log(arguments) //类似数组,但不是数组 let arr:any[]=arguments 报错 //arguments.length 含有一部分数组的方法 //arguments.forEach 不支持 }
//参数 返回值的类型 const isFalsy=(value:any):boolean=>{ return value?true:false } const isFalsy:(value:any)=>boolean=(value)=>{ return value?true:false } //没有返回值 const useMount=(fn:()=>void)=>{ useEffect(()=>{ fn(); }) }
const useHappy=()=>{ return [isHappy,makeHappy,makeUnHappy] } const SomeComponent=()=>{ const [tomIsHappy,makeTomHappy,makeTomHappy]=useHappy(false) }
枚举 对象
//常量 有些范围内的一些系列常量
enum obj{
Up,
Down,
Left,
Right
}
//会自动赋值递增 0123
//赋值的话 Up=10,以此11、12、13
console.log(obj.Up)//0
console.log(obj[0])//'Up'
//字符串枚举
const enum obj{ //加const就是常量枚举
Up='UP',
Down='DOWM',
Left='LEFT',
Right='RIGHT'
}
const value='UP'
if(value===obj.Up){
console.log('go up!')
}
let directions:obj=obj.up
console.log(directions) //UP
let u:undefined = undefined; let u:null = null;
const isFalsy:(value:unknow)=>{ console.log(value.name) //unknown会检验name属性是否存在,而any不做任何检测 } let value:unknow value=1 let v=value //报错,不能把unkonwn类型的值赋值给任何值,也不能读取unknow方法
//函数声明 function add(x:number,y:number,z?:number):number{ //z?可选参数,放在参数最后面 //:number 返回数字类型 } //函数表达式 const add=(x:number,y:number,z?:number):number=>{ //add 函数类型 const add=(x:number,y:number,z?:number)=>number //:number 返回数字类型 } let add2:add1=(x:number,y:number,z?:number)=>number=add //声明函数类型 //冒号后面都是在声明类型 interface Ifun{ (x:number,y:number,z?:number):number } let add2:Ifun=add
function echo(arg:T):T{ //1.T只是泛型的名称,可任意命名 //2.第一个T占位符,可以是任意类型 //3.第二个T参数类型 //4.第三个T返回值类型 return arg } //传入什么类型,返回什么类型 const str:string = 'str' const res=echo(str) //直接填 'str',会进行类型推论 function swap(T,U)(tuple:[T,U]):[T,U]{ return [tuple[0],tuple[1]] //tuple[0]传入的T类型,tuple[1]传入的U类型 } const res2=swap(['string',123]) //函数中 function echoWidthArr (arg:T):T{ console.log(arg.length) //会报错,因为不知道类型是什么,不能确定有length方法 return arg } //解决办法 interFace IWidthLength{ length:number //只要length属性返回number类型 } function echoWidthArr (arg:T):T{ console.log(arg.length) return arg } echoWidthArr('str') echoWidthArr({length:3,width:10}) echoWidthArr([1,2,3]) //类中 class Queue { private data=[]; push(v:T){ //v:number return this.data.push(v) } pop():T{ return this.data.pop(v) } } const q=new Queue //const q=new Queue 可限制推入的类 q.push('123') q.pop().toFixed() //pop的事string类型,却调用了数字方法。我们希望push和pop的类型相同 interface keyPair { key:T value:U } let kp1:keyPair ={key:1,value:'string'} let kp2:keyPair ={key:'1',value:6} let kp3:number[]=[1,2,3] let kp4:Array =[1,2,3]
d.ts
js文件 + .d.ts 文件 === ts 文件
d.ts文件可以让JS 文件继续维持自己JS文件的身份,而拥有TS的类型保护一般我们写业务代码不会用到,但是点击类型跳转一般会跳转到.d.ts文件
interface
接口,创建自己的类型
interface User{ id:number readonly name:string; //只能读不能写 } const u:User={ id:1, name:'你好', } u.name='xxx' //报错
类型别名 type
let sum:(x:number,y:number)=>number const res=sum(1,2) //改变后 type PlusType=(x:number,y:number)=>number let sum1:PlusType const res=sum2(1,2) //联合类型 type strNum=string|number let res1:strNum='123' res1=123 //内容只能等于类型 const str:'name'='name' const num3:1=1 //联合类型 type Direction='up'|'Down'|'left'|'right' let toWhere:Direction='left'//值只能在限定类型中选择 //交叉类型 interface IName{ name:string } type Iperson=IName&{age:number} let person:IPerson={name:'123',age:123}
实用类型
interface IName{ name:string age:number } //Partial可选的 type Ipartial=Partial//IName里面的内容都变成可选的 //Omit可忽略的,第二个参数是可忽略的内容 type IOmit //现在只有age是可选内容