为什么以下通用约束会产生编译器错误?

时间:2019-01-31 12:18:51

标签: generics types compiler-errors type-constraints

以下受约束的泛型函数...

interface Alpha
{
    member1: number,
    member2: string,
}

interface Beta
{
    member1: string,
    member2: string,
}

function convert<Source extends Alpha, Target extends Beta>(s: Source): Target
{
    return {
        ...s,
        member1: s.member1.toString(),
    };
}

const a: Alpha = {member1: 12, member2: 'hello'};
const b: Beta  = convert(a);

...正在产生此编译器错误(其中16行是return语句的开始)

main.ts:16:5 - error TS2322: Type 'Source & { member1: string; }'
               is not assignable to type 'Target'

当然,如果我正在执行编译器的工作,并且自己亲自创建通用函数的特定版本,那么它将按预期工作,而不会出现警告或错误:

function convert(a: Alpha): Beta
{
    return {
        ...a,
        member1: a.member1.toString(),
    };
}

所以我的问题是:

  • 为什么上述定义无法按预期运行?
  • 以及如何以不同的方式表达这种约束以便可以编译?

编译器版本:3.2.2

1 个答案:

答案 0 :(得分:1)

TargetBeta的扩展,可以有许多您不会返回的新字段-您只是在返回Source且字段已更改。

可能的解决方法是更改​​convert's签名以匹配实现:

  function convert<Source extends Alpha>(s: Source): Beta & { member1: string } {}

请记住,无论如何,您将无法从通用类型(相关的TS issue)进行传播