当前位置: 首页 > 知识库问答 >
问题:

前端 - TypeScript创造的联合类型(Mixin)中,如何支持 prototype链判断?如何让 isInherit(C, A) 和 isInherit(C, B) 判定同时成立?

司知
2024-05-25

TypeScript Mixin 创造的联合类型中,如何支持 prototype 链支持?

type Constructor<T = Record<string, any>> = new (...args: any[]) => T;type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;function Mixin<T extends Constructor[]>(...mixins: T): Constructor<UnionToIntersection<InstanceType<T[number]>>> & UnionToIntersection<T[number]>;function Mixin<T extends Constructor[]>(...mixins: T) {    class Mix { }    const mergeDesc: any = {};    function copyProperties(target: any, source: any) {        for (let key of Reflect.ownKeys(source)) {            if (key !== 'constructor' && key !== 'prototype' && key !== 'name') {                let desc = Object.getOwnPropertyDescriptor(source, key);                if (desc) {                    mergeDesc[key] = mergeDesc[key] || [];                    mergeDesc[key].push(desc.value);                    Object.defineProperty(target, key, desc);                }            }        }    }    for (let mixin of mixins) {        copyProperties(Mix, mixin); // 拷贝静态属性        copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性    }    for (const key in mergeDesc) {        const fns = mergeDesc[key];        Object.defineProperty(Mix.prototype, key, {            configurable: true,            enumerable: true,            writable: true,            value(...args: any[]) {                const context = this;                fns.forEach(function (fn: Function) {                    fn.call(context, ...args);                });            },        });    }    return Mix}class A {    printA() {        console.log("A");    }}class B {    printB(sss: string) {        console.log("B");    }}class C extends Mixin(A, B) {    constructor() {        super();    }    printC() {        this.printA();        this.printB('');    }}function isInherit(childClass: any, parentClass: any): boolean {    let child = childClass;    while (child) {        if (child === parentClass) {            return true;        }        child = child.__proto__;    }    return false;}if (isInherit(C, A)) { // 判定不成立    console.log('C inherit A');} else {    console.log('C not inherit A');}if (isInherit(C, B)) { // 判定不成立    console.log('C inherit B');} else {    console.log('C not inherit B');}

共有1个答案

龚盛
2024-05-25
type Constructor<T = Record<string, any>> = new (...args: any[]) => T;type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;function Mixin<T extends Constructor[]>(...mixins: T): Constructor<UnionToIntersection<InstanceType<T[number]>>> & UnionToIntersection<T[number]> {    class Mix {        static mixinClasses = mixins;    }    const mergeDesc: any = {};    function copyProperties(target: any, source: any) {        for (let key of Reflect.ownKeys(source)) {            if (key !== 'constructor' && key !== 'prototype' && key !== 'name') {                let desc = Object.getOwnPropertyDescriptor(source, key);                if (desc) {                    mergeDesc[key] = mergeDesc[key] || [];                    mergeDesc[key].push(desc.value);                    Object.defineProperty(target, key, desc);                }            }        }    }    for (let mixin of mixins) {        copyProperties(Mix, mixin); // 拷贝静态属性        copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性        // 添加标识属性        Mix.prototype[`__is${mixin.name}`] = true;    }    for (const key in mergeDesc) {        const fns = mergeDesc[key];        Object.defineProperty(Mix.prototype, key, {            configurable: true,            enumerable: true,            writable: true,            value(...args: any[]) {                const context = this;                fns.forEach(function (fn: Function) {                    fn.call(context, ...args);                });            },        });    }    return Mix as Constructor<UnionToIntersection<InstanceType<T[number]>>> & UnionToIntersection<T[number]>;}class A {    printA() {        console.log("A");    }}class B {    printB(sss: string) {        console.log("B");    }}class C extends Mixin(A, B) {    constructor() {        super();    }    printC() {        this.printA();        this.printB('');    }}function isInherit(childClass: any, parentClass: any): boolean {    const parentName = parentClass.name;    return childClass.prototype[`__is${parentName}`] === true;}if (isInherit(C, A)) { // 判定成立    console.log('C inherit A');} else {    console.log('C not inherit A');}if (isInherit(C, B)) { // 判定成立    console.log('C inherit B');} else {    console.log('C not inherit B');}
 类似资料:
  • 本文向大家介绍js如何判断类型?相关面试题,主要包含被问及js如何判断类型?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 判断方法:typeof(),instanceof,Object.prototype.toString.call()等

  • 定义如下 使用 出现下面的报错: 为什么在使用typeof的情况下ts对类型判断还是有问题?平常在消费联合类型的时候,都只需要借助typeof就能达到缩小类型范围的目的,但是这里没有效果,我想问下什么时候会出现这种问题? 我知道解决方案: 通过强制的类型断言来告诉ts这是一个函数 通过is关键字来做类型预测 但是不知道什么时候需要这么去解决,只有报错的时候才会尝试这么去解决,恳求大佬解惑。

  • 判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。 下面是大多数编程语言中典型的判断结构的一般形式: 判断语句 C++ 编程语言提供了以下类型的判断语句。点击链接查看每个语句的细节。 语句 描述 if 语句 一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 if...else 语句 一个 if 语句 后可跟一个可选

  • 想实现value是string那么val就是string,value是string[]那么val就是string[]

  • 我在项目中定义了两个 interface , 接下有个函数是处理这两个类型的 我自己想到了用 js 的 is 关键词去判断某个属性是否存在来具体区分这两个 interface ,但是这样好像已经到了 js 的层面了。 问题:在 TS 层面有没有可以实现的方式呢?

  • 怎样让联合类型,支持静态方法呀?