typescript6-高级类型

交叉类型

  1. 将多个类型合并成为一个新的类型,新类型具有所有类型的特性
interface A{
    
    
    name:string
}

interface B{
    
    
    age:number
}
type C=A & B
const c:C={
    
    
    name:'jack',
    age:19
}
console.log(c)

联合类型

  1. 表示必须满足其中一个
// 表示可以是string或者number
const getLengthFunc=(content:string|number):number=>{
    
    
    if(typeof content==='string') return content.length
    else return content.toString().length
}
console.log(getLengthFunc('123')) // 3
console.log(getLengthFunc(123)) // 3

类型保护

  1. 类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型
const getRandomValue=()=>{
    
    
    const num=Math.random()
    if(num>0.5) return '123'
    else return 123
}
const item=getRandomValue();
function isString(value:string|number):value is string{
    
    
    return typeof value === 'string'
}
if(isString(item)){
    
    
    console.log(item.length)
}else {
    
    
    console.log(item.toFixed())
}
  1. typeof类型保护,类型只能是string/number/boolean/symbol中的一种
  2. instanceof类型保护
class CreatClass1{
    
    
    public name='jack'
}
class CreatClass2{
    
    
    public age=20
}
function getRandomClass(){
    
    
    const random=Math.random()
    return random>0.5?new CreatClass1():new CreatClass2()
}
const item=getRandomClass()
if(item instanceof CreatClass1){
    
    
    console.log(item.name)
}else {
    
    
    console.log(item.age)
}

类型别名

  1. 可以对类型名字重新定义
  2. 类型别名可以嵌套
  3. 为接口起别名时,不能使用extends | interface
type TypeString=string
let str:TypeString;
type PositionType<T>={
    
    
    x:T,
    y:T,
}
const position:PositionType<number>={
    
    
    x:1,
    y:1
}
console.log(position)
type Childs<T>={
    
    
    current:T,
    child?:Childs<T>
}
const c:Childs<string>={
    
    
    current:'first',
    child:{
    
    
        current:'second',
        child:{
    
    
            current:'third'
        }
    }
}
console.log(c)
type Direction = 'first' | 'second' | 'third';
function getDirction(direction:Direction){
    
    
    return direction.substr(0,1)
}
// 只能传入 'first' | 'second' | 'third'中的一个
console.log(getDirction('first'))

可辨识联合

  • 具有普通的单例类型属性— 可辨识的特征
  • 一个类型别名包含了那些类型的联合
  • 此属性上的类型保护
interface Square{
    
    
	kind:'Square',
	size:number
} 
interface Rectangle{
    
    
	kind:'Rectangle',
	height:number,
	width:number 
} 
interface Circle{
    
    
	kind:'Circle',
	radius:number 
}
 
 /**  * kind 作为唯一特征,用来做判断  *  */
 type Shape=Square | Rectangle |Circle; 
 function assertNever(value:never):never{
    
    
     throw Error('Unexpected object'+ value) } function getArea(c:Shape):number{
    
    
     switch (c.kind){
    
    
         case 'Square': return c.size;break;
         case 'Rectangle': return c.width*c.height;break;
         case 'Circle': return Math.PI*c.radius**2;break;
         default: return assertNever(c)
     } } const circle:Circle={
    
    
     kind:'Circle',
     radius:20 } console.log(getArea(circle))

多态的this类型

  1. 也就是接口或者类的子类型
  2. 在父类型中方法结束时return当前实例对象出去,让子类不具备此方法但依然可以调用父类的方法
class Counter{
    
    
    constructor(public count:number=0) {
    
    
    }
    public add(value:number){
    
    
        this.count+=value;
        return this;
    }
    public subtract(value:number){
    
    
        this.count-=value;
        return this;
    }
}
const counter=new Counter(10)
counter.add(1).subtract(2)
console.log(counter)
// Counter {count: 9}
class PowCounter extends Counter{
    
    
    constructor(count:number) {
    
    
        super(count);
    }
    public pow(value:number){
    
    
        this.count=this.count**value;
    }
}
const powCounter=new PowCounter(20)
powCounter.pow(2)
powCounter.add(100)
console.log(powCounter)
// PowCounter {count: 500}

索引类型

  • keyof 索引类型查询操作符
  • T[K] 索引访问操作符,也就是T上是否有K
  • 可以检查对象上是否有对应键值对
interface InfoI{
    
    
    name:string,
    age:number
}
let infoProps:keyof InfoI
// infoProps 只能是接口定义的键值
infoProps='name'
infoProps='age'

function getValue<T,K extends keyof T>(obj:T,names:K[]):T[K][]{
    
    
    return names.map(item=>obj[item])
}
const infoObj={
    
    
    name:'jack',
    age:20
}
const infoValue:(string|number)[]=getValue(infoObj,['name','age'])
console.log(infoValue)

映射类型

  • 从旧类型中创建出一个新的类型
  • TS内置Readonly只读和Partial可选
type MapToPromise<T>={
    
    
    [K in keyof T]:Promise<T[K]>
}
type Tuple=[number,string,boolean]
type promiseTuple=MapToPromise<Tuple>
let tuple:promiseTuple=[
    new Promise((resolve) => resolve(1)),
    new Promise((resolve) => resolve('1')),
    new Promise((resolve) => resolve(false)),

]
console.log(tuple)

unknown

  • 任何类型都可以赋值给unknown类型
  • 如果没有类型断言或者基于控制流的类型细化时,unknown不可赋值给其他类型
  • 如果没有类型断言或者基于控制流的类型细化时,不能在上面进行任何操作
  • unknown与任何其他类型组成的交叉类型,返回其他类型
  • unknown与其他类型(除了any是any)组成的联合类型,都等于unknown
  • never是unknown的子类型
  • keyof unknown是never类型
  • 只能对unknown进行等或不等操作,不能进行其他操作
  • unknown类型的值不能访问它的属性,不能作为函数调用,不能作为类创建实例
  • 如果映射用的unknown类型,则不会映射任何类型

条件类型

  • 类似于三元运算符
  • T extends U ? X : Y
type Type<T>=T extends string ? string : number
let type:Type<string>='a'
// 分布式条件类型
type Type2<T>=
    T extends string ? string :
    T extends number ? number :
    T extends ()=>void ? ()=>void :
    object;
type type2=Type2<((()=>void) | number)>
// type2类型为()=>void | number
  • 条件类型的类型推断infer
type Type1<T>=T extends Array<infer U> ? U : T;
type type=Type1<string[]>
  • Exclude 交集 | Extract 并集
type Type1=Exclude<'a'|'b'|'c', 'a'>
// Type1类型为'b'|'c'
type Type2=Extract<'a'|'b'|'c', 'a'>
// Type2类型为'a'
  • NonNullable 去除null和undefined | ReturnType 返回函数的返回类型
type Type1=NonNullable<string | number | null | undefined>
// Type1类型为string | number
type Type2=ReturnType<()=>string>
// Type2类型为string
  • InstanceType根据类型推断出类的类型
class AClass{
    
    
    constructor(public name:number=10) {
    
    
    }
}
type Type1=InstanceType<typeof AClass>
type Type2=InstanceType<any>

猜你喜欢

转载自blog.csdn.net/weixin_64925940/article/details/126808332