Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何向现有对象添加属性以满足typescript中的接口?_Typescript - Fatal编程技术网

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

如何向现有对象添加属性以满足typescript中的接口?,typescript,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; } 我的问题的英文

简而言之,我想做以下几点:

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;
}
someImportantFunction(x:A):B{
var-ret:B=x;
ret.prop2=someCalculation();
返回ret;
}
谢谢,
Mathias更像是一个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;
}
函数某个重要函数(x:A):B{
变量ret:B=x
x、 prop2=someCalculation()
返回ret;
}
使用(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()
  });
}
//典型的mixin函数,如lodash extend或jQuery.extend
//您可以使用其中一个,而不是这种快速而肮脏的实现,
//拥有此函数的主要原因是其类型签名
函数扩展(源代码:T1,添加代码:T2):T1和T2{
让结果=源;
for(让对象的键。键(加法)){
结果[键]=加法[键];
}
返回结果;
}
接口A{
prop1:字符串;
}
接口B扩展了A{
prop2:字符串;
}
函数someImportantFunction(x:A):B{
返回扩展(x{
prop2:someCalculation()
});
}
通过这种方式,编译器可以确定类型
A
缺少类型
B
的哪些属性,并确保
extend
调用提供这些属性。

使用:

由于将返回值定义为(
&
),所以类型出现:

assign(目标:T,来源:U):T&U;

在您提供第二个解决方案的同时,我独立地逐字更新了我的帖子。如果事实证明这确实是最好/唯一的解决方案(我认为是),我会接受你的答案。@mathias999us我也希望有一个更安全的解决方案,但我想不出一个(第一个是最好的类型安全解决方案,但请记住第二个将返回相同的对象x,而不是它的副本,第一个将返回它的副本)使用交叉点类型的可接受答案以类型安全的方式执行此操作。您概述的方法不能保证添加“prop2”to x生成满足类型B的对象。@mathias999us:但它确实满足。
对象。赋值
赋值(目标:T,源:U):T&U;
,与接受的答案几乎相同。@mathias999us更新了答案-您现在应该可以=)
interface A { prop1: string; }
interface B extends A { prop2: string; }

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

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