typescript - Typinträffning för interface
Jag har följande typer:
interface A { a: string }
interface B extends A { b: string }
interface C extends A { c: string }
Jag vill nu skriva följande funktion som returnerar en A:
function test(t: number): A {
return t > 10
? { a: "a", b: "b" }
: { a: "a", c: "c" };
}
Detta fungerar bara om jag uttryckligen kastar de returnerade objekten till A, B eller C, eller om jag skapar separata funktioner som uttryckligen returnerar antingen en B eller en C och använder dessa för att konstruera objektet.
Finns det något sätt för kompilatorn att härleda att det returnerade objektet faktiskt är en B eller en C och därför också en A, utan att jag behöver specificera det?
Svar #1
Min förståelse är att det beror på att TypeScript tillämpar ytterligare begränsningar på objektlitteraler när det gäller överflödiga egenskaper. Om det skrivs om på detta sätt finns det inget fel:
interface A { a: string }
interface B extends A { b: string }
function test(): A {
const result = { a: "a", b: "b" };
return result;
}
Det finns också kompilatoralternativet suppressExcessPropertyErrors.
Svar #2
Det verkar som att TypeScript inte härleder typen av ett objekt till den som definieras av ett interface.
Den härledda typen av { a: "a", b: "b" } är { a: string, b: string }, som kan användas där en A eller en B kan användas, men det är varken A eller B, det är en annan typ.
Så svaret är: nej, kompilatorn kommer inte att härleda A eller B, den kommer att härleda något annat, och en typomvandling är nödvändig om den önskade typen är A eller B.
