美文网首页
常用TS高级类型

常用TS高级类型

作者: yozosann | 来源:发表于2021-09-26 12:32 被阅读0次

    类类型

    写法:

    export interface ConstructorOf<T> {
        new(...args: any[]): T;
    }
    

    应用:

    class BeeKeeper {
      hasMask: boolean = true;
    }
     
    class ZooKeeper {
      nametag: string = "Mikle";
    }
     
    class Animal {
      numLegs: number = 4;
    }
     
    class Bee extends Animal {
      keeper: BeeKeeper = new BeeKeeper();
    }
     
    class Lion extends Animal {
      keeper: ZooKeeper = new ZooKeeper();
    }
    
    function createInstance<A extends Animal>(c: ConstructorOf(A)): A {
      return new c();
    }
    
    createInstance(Lion).keeper.nametag;
    createInstance(Bee).keeper.hasMask;
    

    函数返回类型

    写法:

    type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;
    

    参数类型

    写法:

    type Parameters<T> = T extends (...args: infer R) => any ? R : any;
    

    应用:

    type T0 = Parameters<() => string>;  // []
    type T1 = Parameters<(s: string) => void>;  // [string]
    type T2 = Parameters<(<T>(arg: T) => T)>;  // [unknown]
    

    类型推导infer

    参考

    https://blog.csdn.net/KlausLily/article/details/108878205

    题目:https://github.com/LeetCode-OpenSource/hire/blob/master/typescript_zh.md
    interface Action<T> {
        payload?: T;
        type: string;
    }
    
    class EffectModule {
        count = 1;
        message = "hello!";
    
        delay(input: Promise<number>) {
            return input.then(i => ({
                payload: `hello ${i}!`,
                type: 'delay'
            }));
        }
    
        setMessage(action: Action<Date>) {
            return {
                payload: action.payload!.getMilliseconds(),
                type: "set-message"
            };
        }
    }
    
    答案:

    1.首先要将方法给解出来:

    type MethodName<T> = {
        [F in keyof T]: T[F] extends Function ? F : never;
    }[keyof T];
    

    2.其次将源函数和目标函数做一个对比:

    type asyncMethod<T, U> = (input: Promise<T>) => Promise<Action<U>>;
    // 转化为
    type asyncMethodConnected<T, U> = (input: T) => Action<U>;
    
    type syncMethod<T, U> = (action: Action<T>) => Action<U>;
    // 转化为
    type syncMethodConnected<T, U> = (action: T) => Action<U>;
    

    3.用infer来推导类型,做转发:

    type EffectMethodAssign<T> = T extends asyncMethod<infer U, infer V> ? asyncMethodConnected<U, V> : T extends syncMethod<infer U, infer V> ? syncMethodConnected<U, V> : never;
    

    4.将两个优化结合:

    type Connect = (module: EffectModule) => {
        [F in MethodName<typeof module>]: EffectMethodAssign<typeof module[F]>
    };
    

    联合类型

    type UnionToIntersection<U> = 
        (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
    
    function mixIt<T extends any[]>(...args: T): UnionToIntersection<T[number]>{ 
        let mixin: any =  {};
    
        args.forEach( obj => {
            for(let key in obj) {
                if( ! mixin.hasOwnProperty(key) ) {
                    mixin[key] = obj[key];
                }
            }
        });
    
        return mixin;
    }
    
    class X {x: number = 7;}
    class Y {y: string = 'ok';}
    class Z {z: boolean = false;}
    
    let x = new X;
    let y = new Y;
    let z = new Z;
    
    let xy = mixIt(x, y);
    let xyz = mixIt(x, y, z);
    

    解构

    class Plugin {}
    class LandingPlugin extends Plugin {
        a: string;
    }
    class ShareCore extends Plugin {
        b: string;
    }
    
    interface PluginConfig<M> {
        config?: any;
        bindings?: Array<keyof M>; 
    };
    export type PluginOption<M> = [ConstructorOf<M>, PluginConfig<M>?, any?, boolean?];
    function ReinforcePage5<T extends Plugin[]>(c: {
        pluginOptions: [
            ...{[K in keyof T]: PluginOption<T[K]>}
        ]
    }): void {};
    
    ReinforcePage5({
        pluginOptions: [
            [LandingPlugin, {
                bindings: ['a']
            }],
            [ShareCore, {
                bindings: ['b']
            }]
        ]
    });
    

    相关文章

      网友评论

          本文标题:常用TS高级类型

          本文链接:https://www.haomeiwen.com/subject/xesqnltx.html