基础知识
基础静态类型
在typescript中基础类型跟我们JavaScript中基础类型是一样的,只是有个别是Ts里面新出的
number
const count:number=18 //显示注释一个number类型
const count1=18 //不显示注释,ts会自动推导出类型
string
const str:string="前端娱乐圈" //显示注释一个number类型
const str1="蛙人" //不显示注释,ts会自动推导出类型
boolean
const status:string=false; //显示注释一个string类型
const status1=true; //不显示注释,ts会自动推导出注释
null
const value:null=null
const value:null=undefined //这一点null类型可以赋值undefined跟在js中一样的 null==undefined
undefined
const value:undefined=undefined
const value:undefined=null //这一点null类型可以赋值undefined跟在js中是一样的,null==undefined
void
void在ts中是代表无效的,一般用于函数上,告诉别人这个函数是没有返回值的
function fn():void{} //正确
function testFn():void{
return 1; //报错,不接受返回值的存在
}
function fn1():void{return undefined} //显示返回undefined类型,也是可以的
function fn2():void{return null} //显示返回null类型也可以,应为null==undefined
never
never一个永远不会有值的类型或者也可以说一个永远也执行不完全的类型,代表用于不会有值,
undefined、null也算做值,一般这个类型就不会用到,也不用
const test:never=null //错误
const test1:never=undefined //错误
function Person():never{ //正确,因为死循环了,一直执行不完
while(true){}
}
function Person():never{ //正确,因为递归,永远没有出口
Person()
}
function Person():never{ //正确,代码报错了,执行不下去
throw new Error()
}
any
any这个类型代表任何的、任意的,
let value:any="" //正确
value=null //正确
value={} //正确
value=undefined //正确
unknown
unknown类型是我们ts中第二个any类型,也是接受任意的类型的值
let value:unknown=""
value=1
value="fdsfs"
value=null
value={}
any和unknown区别
let valueAny:any=""
let valueUnknown:unknown=""
valueAny="蛙人"
valueUnknown="前端娱乐圈"
let status:null=false
status=valueAny //正确
status=valueUnknown //报错,不能将unknown类型分配给null类型
对象静态类型
object&&{}
{},object表示非原始类型,也就是除number、string、Boolean、symbol、null或undefined之外的类型
const list:object={}
const list1:object=null //null对象
const list:object=[] //数组对象
const list:{}={}
list.name=1 //报错 不可更改里面的字段,但是可以读取
list.toString()
数组
const list:[]=[] //定义一个数组类型
const list1:number[]=[1,2] //定义一个数组,;里面值必须是对象类型的
const lists2:object[]=[null,{},[]] //定义一个数组里面必须是对象类型的
const list3:Array<number>=[1,2,3] //泛型定义数组必须是number类型,
类
//类
class ClassPerson={
name:'前端娱乐圈'
}
const persoon:ClassPerson=new Person()
person.xxx=123 //这行代码报错,因为当前类中不存在改xxx属性
函数
//函数
const fn:()=>string=()=>"前端娱乐圈" //定义一个变量必须是函数类型,返回值必须是string类型
函数类型注解
函数返回类型为number
function fn(a,b):number{
return a+b
}
fn(1,2)
函数void
显示注解为void类型,函数没有返回值
function fn():void{
console.log(1)
}
函数不会自动类型推导
可以看到下面的函数类型,不会自动类型推导,我们实参虽然传入的1和2,但是形参方面是可以接受任意类型值的,所以系统也识别不出来你传递的什么
function testFnQ(a:any,b:any):any{
return a+b
}
testFnQ(1,2)
function testFnQ(obj:{num:number}){
return obj.num
}
testFnQ({num:18})
元组Tuple
元组用于表示一个已知数组的数量和类型的数组,定义数组中每一个值的类型,一般不经常使用
const arr:[string,number]=["前端娱乐圈",1]
const arr:[string,string]=["前端娱乐圈",1] //报错
枚举Enum
Enum枚举类型,可以设置默认值,如果不设置则为索引
enum color{
RED,
BLUE="blue",
GREEN="green"
}
// color["RED"] 0
// color["BLUE"] blue
enum可以递增值,也可已设置默认值,enum没有JSON对象灵活,enum不能在任意字段上设置默认值
接口Interface
接口interface是什么,接口interface就是方便我们定义一处代码,多处复用。接口里面也存在一些修饰符
接口怎么复用
比如在讲到这之前,我们不知道接口这东西,可能需要给对象定义一个类型
const testObj:{name:string,age:number}={name:'测试',age:18}
const testObj:{name:string,age:number}={name:'测试1',age:18}
//接口改造
interface Types{
name:string,
age:number
}
const testObj:Types={name:'测试',age:18}
const testObj1:Types={name:'测试1',age:18}
readonly修饰符
readonly类型,只可读状态,不可更改
interface Types{
readonly name:string,
readonly age:number
}
const testObj:Types={name:'测试',age:18}
const testObj1:Types={name:'测试1',age:18}
testObj.name="张三" //无法更改name属性设置只可读
testObj1.name="李四" //无法更改name属性设置只可读
?可选修饰符
可选修饰符以?定义,为什么需要可选修饰符呢,如果不写
可选修饰符
,那interface里的属性都是必填的
interface Types{
readonly name:string,
readonly age:number,
sex?:string
}
const testObj:Types={name:'测试',age:18}
extends继承
我们的
interface
也是可以继承的,跟ES6class
类一样,使用extends关键字
interface Types{
readonly name:string,
readonly age:number,
sex?:string
}
interface ChildrenType extends Types{
hobby:[]
}
const testObj:ChildrenType={name:'测试',age:18,hobby:["code","羽毛球"]}
propName扩展
interface里面这个功能就很强大,他不用写入interface里的属性
interface Types {
readonly name:string,
readonly age:number,
sex?:string,
[propName:string]:any
}
const testObj:Types={name:'测试',age:18,hobby:[]}
Type
这个是声明类型别名使的,别名类型只能定义是:
基础静态类型
、对象静态类型
、元组
、联合类型
type Types=string
type TypeUnite=string|number
const name:typeUnite="测试"
const age:typeUnite=18
type不支持interface声明
type Types=number
type Types=string //报错,类型别名不能出现重复名字
interface Type1{
name:string
}
interface Type1{
age:number
}
// interface接口可以出现重复类型名称,如果重复出现则是,合并起来也就是变成{name:string,age:number}
interface如果两个接口,里面的属性也是同名称,但是类型不一样,第二个interface会爆红
type支持表达式interface不支持
const count:number=123
type testType=typeof count
const count:number=123
interface testType{
[name:typeof count]:any //报错
}
type支持类型映射,interface不支持
type keys="name" | "age"
type KeysObj={
[propName in keys]:string
}
const PersonObj:KeysObj={ //正常运行
name:'测试',
age:"18"
}
interface testType{
[propName in keys]:string //报错
}
联合类型
联合类型是用
|
表示,说白了就是满足其中的一个类型
就可以了
const statusTest:string|number='前端娱乐圈'
const flag:boolean|number=true
- typeof
function testStatusFn(params:string|number){
if(typeof params =='string'){
console.log(params.split)
}
if(typeof params == 'number'){
console.log(params.toFixed)
}
}
- in
function testStatusFn(params:frontEnd|backEnd){
if("name" in params){
console.log(params.name)
}
if("age" in params){
console.log(params.age)
}
}
- as断言
function testStatusFn(params:frontEnd|backEnd){
if("name" in params){
const res=(params as frontEnd).name
console.log(res)
}
if("age" in params){
const res=(params as backEnd).age
console.log(res)
}
}
testStatusFn({age:118})
交叉类型
交叉类型就是跟联合类型相反,他是用
&
表示,交叉类型必须存在,例:
interface frontEnd{
name:string
}
interface backEnd{
age:number
}
function testStatusFn(params:frontEnd&backEnd){
}
testStatusFn({age:118,name:'前端娱乐圈'})
泛型
泛型,函数参数
注解类型
定义string和number,调用函数实参传入也没什么问题,但是有个需求,就是实参我们必须传入同样的类型(传入的两个number类型)。这种联合类型也可以实现,但是如果我们要加个boolean类型,这样联合类型还需追加个Boolean类型,这样会造成代码的冗余 ,泛型是专门针对不确定的类型使用,并且灵活。泛型的使用大部分都是使用,当然也可以随便使用,如:、
function test<T>(a:T,b:T){
console.log(a,b)
}
test<number>(1,"前端娱乐圈") //报错
test<boolean>(true,false)
test<string>("前端娱乐圈","蛙人")