Typescript: Varför är en utelämnad generisk typ ett objekt?
Jag undrar varför den förvalda generiska typen är ett objekt {} och inte any? Den beter sig som en any, men är lite förvirrande.
Exempel/Demo
class Foo<T> {}
// The type of this:
const foo = new Foo();
// is {} but expected any or error.
Jag skulle kunna använda:
class Foo<T = any> {}
Men jag vill veta bakgrunden bakom. Jag tror att det är eftersom T är objekt-liknande.
En annan fråga: Hur tvingar man utvecklaren att sätta en typ för den generiska klassen?
Svar #1
Detta är standardbeteendet som TypeScript har när det gäller generiska typparametrar. Det försöker härleda dem, och om det inte kan gör det så använder det den snävaste möjliga typen, vilket om du inte har några begränsningar på T är {}
Som @Paleo påpekar i kommentarerna finns det ett förslag om att skapa ett strict-alternativ för detta, men det är inte tillgängligt för närvarande:
Under tiden, om vi vill tvinga fram specificering av parametrar kan vi leka med konstruktörsparametrarna, för att få ett fel om ingen typparameter anges:
class Foo<T = void> {
constructor(...a: T extends void ? ["Supply A type arg"] : []) {
}
}
const foo1 = new Foo(); // err
const foo2 = new Foo<number>();
Notera Jag skulle använda detta trick sparsamt, och föredra att ha ett argument till konstruktorn som låter kompilatorn härleda T. Även utan detta trick skulle du så småningom förmodligen få ett felmeddelande att {} inte är vad du kanske förväntar dig, även om det kan vara ett problem att spåra felet.
