Der Hauptanwendungszweck von Interfaces ist, den Nutzer einer Klasse von ihrer tatsächlichen Implementierung zu trennen. Er sieht nur das Interface, und wie es implementiert ist, hat ihn nicht zu interessieren. Das Interface stellt den Kontrakt dar, der bereitgestellt wird und den ich nutzen kann. Durch die Trennung zwischen Kontrakt und Ausführung des Kontrakts entsteht Austauschbarkeit und insbesondere die Möglichkeit zum Mocken und Unit-Testen. Statische Typchecks sind nur ein Aspekt des Ganzen. Mit einer passenden Remoting-Library darunter kann ich mir bei einer Factory ein Interface bestellen und sie schiebt mir, wenn es so konfiguriert ist, klammheimlich einen Remote-Aufruf unter. Oder eben nicht, wenn ich den Service lokal nutze. Sowas geht nur mit Interfaces (oder, ja, abstrakten Superklassen, die ich wie Interfaces nutze).
In Sprachen wie PHP oder JavaScript kann man Interfaces tatsächlich auf ein technisches Muster für vorhandene Klassenelemente reduzieren, weil die Bindung Aufruf->Implementierung zur Laufzeit erfolgt.
Für die Diskussion muss man bei „Eigenschaften“ genau hinsehen und zwischen Property und Field unterscheiden. Ein Field ist das nackige, unverfälschte Datenelement, das am Objekt hängt und nur einen Wert darstellt. Also das, was ich in PHP über $obj->Dings = 17
anspreche und annähernd das, was ich in JavaScript über obj = { Dings: 17 };
erzeuge. Dem entgegen steht ein Ding, das ich zur Abgrenzung mal Property nenne, das ich von der Syntax her wie ein Field behandle, wo die Zugriffe aber technisch auf einen Methodenaufruf abgebildet werden bzw. zumindest abgebildet werden können.
In JavaScript ist es so, dass Eigenschaften in zwei Facetten vorkommen. Als Data-Properties, die einen Wert besitzen und vom Verhalten her einem Field entsprechen, oder als Accessor-Properties, die Get- und Set-Methoden haben. Der Nutzer bekommt das überhaupt nicht mit. Die Syntax ist für ihn die gleiche. Die gleiche Mimik hat z.B. C# mit seiner get/set Syntax. Auch da ist für den Aufrufer ein Field von einem Property syntaktisch nicht zu unterscheiden (semantisch schon: bei readonly und call-by-reference).
Java gibt sich gar nicht erst die Mühe, hier irgendwas zu zuckern, da gibt's nur die getXxx und setXxx Konvention und das wird dann Property genannt...
D.h. eine Eigenschaft in einem TypeScript-Interface ist unproblematisch, weil bei der Implementation jederzeit ein Accessor-Property unterlegt werden kann. In Java stellt sich die Frage nicht. In C# ist es wie in Java, nur unter einer Zuckerkruste versteckt und man hat das Gefühl, als gäbe es Eigenschaften auf Interfaces.
PHP hat weder diese duale Darstellung von Data- und Accessor-Properties, noch den get/set Syntaxzucker. Wenn ich in ein PHP Interface eine Eigenschaft schreibe, bedeutet das zur Laufzeit den direkten Zugriff auf ein Field. Und DAS ist ein Problem, weil ich ein Field nicht mocken oder nach Bedarf durch einen Methode substituieren kann. Deswegen muss ich in PHP, genau wie in Java, ein interfacefähiges Property durch explizite Getter und Setter realisieren.
Rolf