一、类型注解
如:number是类型注解
具体分为:
原始类型、数组类型2、联合类型|、类型别名type(交叉&)、keyof(获取key字面量)、函数类型2(void不确定函数返回值,可选参数?不确定参数)、对象类型:{}、字面量类型(类似const)、接口interface、类型推断(自动)、any类型、类型断言as(常和typeof)、泛型<>(不确定某个类型)。各个模块作用,使用场景。什么场景可以增未定义类型的值
:一般定义的类型,定义实际变量时类型不对或没写会报错。
不同抽离类型方式的区别和使用场景:
1.普通类型别名type通过变量名抽离,简化的是type部分

2.继承、交叉
鼠标放赋值后的变量有提示,先写值,可以cv
1.原始类型
: number 就是类型注解
// 约定变量 age 的类型为 number 类型
let age: number = 18;
age = 19;
// name后续也只能修改为number
*、ts类型
js类型8:Number/String/Boolean/Null/Undefined/Symbol/Bigint/Object
简单数据类型:Number/String/Null/Boolean/Undefined
复杂数据类型:Object:Array/Function/普通对象

ts除简单类型注解外,
2.数组类型
// 两种写法
let arr:Array<number>=[1,2,3,4]
let arr2:number[]=[1,2,3,4]
3.联合类型
定义num变量是number或string类型,可以在这两种类型修改
var num:number|string=1
num='jack'
对象里面规定的类型不对或没写会报错
var m:{id:number,name:string}|number|number[]={id:1,name:'jack}
// 可以把对象里面类型也写死,发请求在因为类型导致请求出错之前,自己就会报错,更方便检查
let arr4:(number|string|string[])[]=[1,2,3,'4',['2']]
4.类型别名
作用:简化代码
重复使用某种类型,可以抽离(外层里层都可以写成类型别名,关键字type)
type N=number
type T={
id: N;
name: string;
hobby: string[];
family: {
mather: string;
}
}[]
var list:T=[
{
id: 1,
name: 'jack',
hobby: ['游泳'],
family: {
mather: '妈妈'
}
}
]
//如果有报错,可能是类型名是关键字,换个类型名
5.函数类型


?
(1)普通函数写法(分别指定)//尽量只在箭头函数抽离(同时指定)
function add(a:number,b:number):string{
return '1'
}
add(1,2)
(2)箭头函数写法(分别指定)
const add2=(a:number,b:number):string=>{
return '1'
}
add2(1,2)
(2.1)外层箭头函数写法(同时指定)
const add3:(a:number,b:number)=>string=(a,b)=>{
return '1'
}
add3(1,2)
(2.2)箭头函数抽离
type T2=(a:number,b:number)=>string
const add4:T2=(a,b)=>{
return '1'
}
add4(1,2)


补充:普通函数和箭头函数标准写法的区别,如上图所示
(3)函数返回值不确定时:void类型
对于函数返回值不确定的,可以使用void,此时可以不return
// void
type F=(a:number,b:number)=>void
const fn:F=(a,b)=>{
// return '1'
}
如果这个位置指定undefined则必须是undefined值和类型必须都是undefined
此时必须写return undefined //不写return 或return;都不符合
// =>undefined必须写return undefined区分值和类型
// 即返回值必须是undefined而不是返回类型必须是undefined
type F2=(a:number,b:number)=>undefined
const fn2:F2=(a,b)=>{
// return '1'
return undefined
}
*、参数类型可传可不传时:可选参数(参数后面,除普通函数外冒号前面加?)
// 可选参数
// 对象
const obj23:{
age?:number
name:string
}={
name:'jack'
}
// 函数
type F5 = (a?: number, b?: number) => void
const add5: F5 = (a, b) => {
// return 12
}
add5()
// 普通函数和箭头函数
type L = {
id?: number,
name: string
hobby: string[],
family: {
mather: string
}
say?: () => number,
// fn:()=>number
// say():number,
fn?(): number
}[]
//
var list2: L = [
{
// id: 1,
name: 'jack',
hobby: ['游泳'],
family: {
mather: '妈妈'
},
}
]
6.对象类型+8.字面量类型
// 字面量类型: var 实现const 效果
const num11=1234
var num12:1234=1234
// 对象类型+字面量类型
const obj2:{
// 字面量类型
id:2,
age:number
name:string
}={
id:2,
age:18,
name:'jack'
}
*、接口interface和type类比reactive和ref
interface一般用于对象类型,type用于所有类型
interface通过继承复用,type通过交叉类型复用
interface可以重复定义相同变量名同extends作用,建议用extends,type不可以重复定义相同变量名
// interface相比type不写=
type Pperson={
id:number
name:string
}
const obj3:Pperson={
id:1,
name:'jack'
}
interface Iperson {
id:number
name:string
}
const obj4:Iperson={
id:1,
name:'jack'
}
interface 继承和type交叉
interface可以重复定义相同变量名,不会覆盖会合并所有要求,但建议用extends
// interface继承和type交叉,Iperson和Tperson是interface和type定义好的类型规定,代码省略
// interface继承 关键字extends
interface Iperson2 extends Iperson{
age:number
hobby:string[]
}
//等价于上一段代码,interface可以重复定义相同变量名,不会覆盖会合并所有要求,但建议用extends
interface Iperson{
age:number
hobby:string[]
}
const obj6:Iperson2={
id:1,
name:'jack',
age:18,
hobby:['游泳']
}
// type交叉
// type不可以重复定义相同变量名
type Tperson2= Tperson &{
age:number
hobby:string[]
}
const obj5:Tperson2={
id:1,
name:'jack',
age:18,
hobby:['游泳']
}

7.类型推断
写完赋值,鼠标放上可以自动推断出类型
var num5=123
9.any类型
不知道数据类型用any不建议,因为违背了typescript强语言规范
// any
var add6:any=(num1,num2)=>{
return num1+num2
}
add6(1,'2')
add6=2
10.类型断言 as
明确知道获取的更具体的数据类型
// 类型断言
const aLink=document.getElementById('link')
const aLink2=document.getElementById('link') as HTMLAnchorElement
还有在当确定数据之后的类型,但不想附初始值时使用
常用typeof和as配合+补充keyof
// 类型断言2
const obj={
id:1,
name:'jack'
}
// =右侧返回是类型,常用typeof和as配合
type Tperson3=typeof obj
const obj7={} as Tperson3
// keyof获取到值类型的键,获取到把键变成的字面量的联合类型
type P=keyof Tperson3 // keyof +的是type生命的变量
var p1:P='name' // p只能赋值为'id'或'name'


11.泛型<>
有部分类型可以由传的类型来决定,本质是类型抽离
1.泛型类型别名
// 泛型
type Goods={
id:number,
goodsName:string
}
type Data<T>={
id:number,
hobby:string[],
res:T // 类似函数传参,可以?不带这个属性,但是传参是必须传T,除非<T=number>有初始值
}
type Data1=Data<number>
type goodsData=Data<Goods>
const d1:Data1={
id:1,
hobby:['12'],
res:1
}
const goods1:goodsData={
id:1,
hobby:['34'],
res:{
id:1,
goodsName:'12'
}
}
2.泛型接口
单层
// 泛型 接口
interface Iperson4<T4> {
id:number,
name:string,
data:T4
}
type Tperson4=Iperson4<number>
const tper4:Tperson4={
id:1,
name:'2',
data:1
}
3.泛型函数
一般不用箭头函数
// 函数泛型<>
function getId<T>(id:T):T{
return id
}
let id1=getId<number>(1)
// 此处可省略传T类型,因为自动类型推断了T为number
let id2=getId(2)
// T是上面声明了,Q没声明,两种情况
// 无<>,T必须定义好;函数注意参数和返回值除定义类型外的逻辑冲突

<>内从右往左分析
二、补充:
1.type除了赋值number等,还可以用类型别名定义的字面量类型
作用类似字面量
// 补充类似字面量类型,用类型别名定义的字面量类型
type Direction='up'|'down'|'left'|'right'
function add9(d:Direction){
return d
}
add9('down')
2.枚举类型
关键字enum
类似对象找属性
类比interface
// 枚举类型 基础用法
enum Day {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
function add10(Day:Day){
return Day
}
add10(Day.Monday)
//
js编译结果:

三、综合案例
总结


类型声明文件