如何将属性添加到现有对象以满足typescript中的接口?

时间:2015-12-28 13:53:03

标签: typescript

这就是我想简单说明的事情:

interface A {
     prop1: string;
}

interface B extends A {
    prop2: string;
}

someImportantFunction(x: A): B {
    var ret: B = x.prop2 = someCalculation(); //Error, but if possible x would now satisfy B

    return ret;
}

我的问题的英文版是:如何在typescript中为现有对象添加新属性,目标是满足更多派生的接口定义?也许这是不可能的,或者我错过了一些明显的方法。

更新: 另外,假设接口A上的属性列表很长,因此通过映射属性进行样板分配是费力且不干净的。

我也看到这样的东西会起作用,但它似乎是一个黑客:

someImportantFunction(x: A): B {
    var ret: B = <B>x;
    ret.prop2 = someCalculation();

    return ret;
}

谢谢, 的Mathias

3 个答案:

答案 0 :(得分:4)

使用intersection types(TS 1.6+),您可以拥有更多类型安全性:

// your typical mixin function, like lodash extend or jQuery.extend
// you can use one of those instead of this quick and dirty implementation,
// the main reason for having this function is its type signature
function extend<T1, T2>(source: T1, addition: T2): T1 & T2 {
  let result = <T1 & T2>source;
  for(let key of Object.keys(addition)) {
    result[key] = addition[key];
  }
  return result;
}

interface A {
  prop1: string;
}

interface B extends A {
  prop2: string;
}

function someImportantFunction(x: A): B {
  return extend(x, {
    prop2: someCalculation()
  });
}

这样,编译器可以确定类型B中缺少A类型的哪些属性,并确保您的extend调用提供它们。

答案 1 :(得分:1)

使用Object.assign

interface A { prop1: string; }
interface B extends A { prop2: string; }

someImportantFunction(x: A): B {
    var ret: B = Object.assign(x, { prop2 : someCalculation()});

    return ret;
}

由于the typing file而出现的类型将返回值定义为intersection type&):

assign<T, U>(target: T, source: U): T & U;

答案 2 :(得分:0)

这更像是一个JavaScript问题:

function someImportantFunction(x: A): B {
    var ret: B = {
        prop1: x.prop1,
        prop2: someCalculation()
    }

    return ret;
}

但您也可以这样做:

function someImportantFunction(x: A): B {
    var ret: B = <B>x
    x.prop2 = someCalculation()

    return ret;
}