Reputation: 357
Here's what I would like to do in a nutshell:
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;
}
The english version of my question is: how can I add new properties to an existing object in typescript, with the goal of satisfying a more-derived interface definition? Perhaps this is not possible, or I am missing some obvious approach.
UPDATE: Also, suppose the list of properties on interface A is long, so boilerplate assignment by mapping properties is laborious and not clean.
I also see something like this would work, but it seems like a hack:
someImportantFunction(x: A): B {
var ret: B = <B>x;
ret.prop2 = someCalculation();
return ret;
}
Thanks, Mathias
Upvotes: 11
Views: 11696
Reputation: 5128
Use 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 types come out because of the typing file defines the return values as an intersection type (&
):
assign<T, U>(target: T, source: U): T & U;
Upvotes: 6
Reputation:
With intersection types (TS 1.6+), you can have more type safety:
// 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()
});
}
This way the compiler can determine what properties of type B
are missing from type A
and ensure your extend
call provides them.
Upvotes: 6
Reputation: 13211
It's more a JavaScript-Problem:
function someImportantFunction(x: A): B {
var ret: B = {
prop1: x.prop1,
prop2: someCalculation()
}
return ret;
}
but you could also do:
function someImportantFunction(x: A): B {
var ret: B = <B>x
x.prop2 = someCalculation()
return ret;
}
Upvotes: 0