Hur lägger man till en egenskap till ett befintligt objekt för att uppfylla ett gränssnitt i TypeScript?
Här är vad jag skulle vilja göra i korthet:
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;
}
Den engelska versionen av min fråga är: hur kan jag lägga till nya egenskaper till ett befintligt objekt i TypeScript, med målet att uppfylla en mer härledd gränssnittsdefinition? Kanske är detta inte möjligt, eller så missar jag någon uppenbar metod.
UPPDATERING: Antag också att listan över egenskaper på gränssnitt A är lång, så rutinmässig tilldelning genom att mappa egenskaper är arbetsam och inte ren.
Jag ser också att något liknande detta skulle fungera, men det verkar vara ett hack:
someImportantFunction(x: A): B {
var ret: B = <B>x;
ret.prop2 = someCalculation();
return ret;
}
Tack, Mathias
Svar #1
Med intersektionstyper (TS 1.6+) kan du få mer typkontroll:
// 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()
});
}
På så sätt kan kompilatorn avgöra vilka egenskaper av typen B som saknas i typen A och säkerställa att ditt extend-anrop tillhandahåller dem.
Svar #2
Använd 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;
}
Typerna kommer fram eftersom typningsfilen definierar returvärdena som en intersections typ (&):
assign<T, U>(target: T, source: U): T & U;
