首页 > 解决方案 > 交集类型如何与多态 this 和泛型结合使用?

问题描述

以下代码片段无法编译,我不明白为什么。抱歉,有点冗长,这是我能找到的最小的 MWE。

interface Num {
    num: number;
}

class Base {
    num?: number;
    base(): this {
        return this;
    }

    addNum(): this & Num {
        this.num = 1;
        return this as this & Num;
    }
}

function unwrapNum<B extends Base>(base: B): B & Num {
    return base.addNum().base();
}

它失败并出现错误:

Type 'B' is not assignable to type 'B & Num'.
  Type 'Base' is not assignable to type 'B & Num'.
    Type 'Base' is not assignable to type 'B'.
      'Base' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'Base'.
        Type 'B' is not assignable to type 'Num'.
          Type 'Base' is not assignable to type 'Num'.
            Types of property 'num' are incompatible.
              Type 'number | undefined' is not assignable to type 'number'.
                Type 'undefined' is not assignable to type 'number'.

我的理解是输入类型B在调用addNum它之后应该变成B & Num如果我打破那个分配它看起来的样子。但是,当我调用base()它时,结果没有B & Num我期望/想要的类型,而是只有B,这意味着某些东西没有按预期工作。我的预感是这与多态 this 有关,例如(B & Num).base()没有 type B & Num

但是,如果我使用以下内容删除泛型:

const base = new Base();
const numed: Base & Num = base.addNum();
const numed2: Base & Num = numed.base();

它工作得很好,所以感觉它是通用 Base、多态 this 和交集类型的组合。

奇怪的是,如果包装在另一个泛型中,它确实可以编译:

function unwrapNum<B extends Base>(base: B): B & Num {

    function helper<BN extends B & Num>(b: BN): BN {
        return b.base();
    }

    return helper(base.addNum());
}

感谢 Aleksey L. 提供更小的 MWQ

标签: typescriptthis

解决方案


推荐阅读