Tslint: interface-over-type-literal sollte nicht empfohlen werden

Erstellt am 25. Sept. 2017  ·  18Kommentare  ·  Quelle: palantir/tslint

Ja, ich weiß, dass die Typescript-Dokumente sagen

Da es eine ideale Eigenschaft von Software ist, offen für Erweiterungen zu sein, sollten Sie eine Schnittstelle nach Möglichkeit immer über einen Typ-Alias ​​verwenden.

Aber im Ernst, wenn ich einen einfachen Typ mache, ohne die Absicht, ihn jemals als erweiterbares Ding zu verwenden, macht es keinen Sinn, ihn als Schnittstelle zu codieren.

API Breaking Change Enhancement

Hilfreichster Kommentar

Ich weiß, dass ich es außer Kraft setzen kann, aber ich bin ziemlich stark davon überzeugt, dass die Empfehlung falsch ist.

Hier ist meine Sicht darauf. Es gibt viele Fälle, in denen eine Schnittstelle nicht für einen Typalias verwendet werden kann. Sie können eine Schnittstelle nur verwenden, um ein Objektliteral einzugeben. Wenn ich die empfohlenen Best Practices befolgen soll, dann werden in einer bestimmten Klassendatei, in der ich möglicherweise mehrere Typaliase habe, einige Typaliase und einige Schnittstellen sein. Jemand, der über diese Klasse stolpert, wird sich fragen, was zum Teufel los ist und ob ich beabsichtige, die Schnittstellen irgendwo zu implementieren/erweitern, oder zumindest erwarte, dass dies eine Möglichkeit ist.

Meiner Meinung nach wäre es viel sauberer für mich, einen Typ-Alias ​​für einen Typ-Alias ​​und eine Schnittstelle für eine Schnittstelle zu verwenden, anstatt in einigen Fällen einen durch den anderen zu ersetzen, nur weil Schnittstellen einige zusätzliche Fähigkeiten haben (die ich nicht brauche). wenn alles will, ist ein Typ-Alias).

Ich nehme an, ich sollte ein Problem gegen die Typoskript-Dokumentation schreiben, was ich tun werde, aber ich denke, dass hier ein technisches Urteil angewendet werden kann, anstatt eine Regel zu implementieren, nur weil die Dokumentation sagt, dass Sie es tun sollten.

Alle 18 Kommentare

Tut mir leid, ich verstehe nicht, was du meinst. Ist dies eine Funktionsanfrage oder ein Fehlerbericht?

Der Standardwert für „interface-over-type-literal“ in „recommended.ts“ ist „true“. Ich glaube, es sollte falsch sein. Ich bin mir nicht sicher, ob das eine Funktionsanfrage oder ein Fehler ist :-)

Immerhin ist das empfohlene Preset rechthaberisch. Es enthält Best Practices und Vorschläge wie die, die Sie oben gepostet haben.
Beim Erweitern einer Voreinstellung können Sie die Empfehlung außer Kraft setzen und die Konfiguration an Ihre Bedürfnisse anpassen.

Wie auch immer, das Deaktivieren der Regel wäre eine Breaking Change. Erwarten Sie also keine Änderung vor der nächsten Hauptversion.


Zur Verdeutlichung: interface-over-type-literal beschwert sich nur über Typ-Alias-Deklarationen.

type Foo = {foo: number}; // The rule disallows this
interface Foo {foo: number} // and fixes it to this

let obj: {foo: number}; // This is still allowed

Da ein Typ-Alias ​​und eine Schnittstelle (fast) austauschbar verwendet werden können, verstehe ich nicht, warum Sie den Typ-Alias ​​bevorzugen würden.

In einem ähnlichen Zusammenhang: Schnittstellen wurden früher zwischengespeichert, während anonyme Typen wie Typaliase für die Verwendung neu berechnet wurden. Daher könnte die Verwendung von Typaliasen die Kompilierzeit erheblich verlängern.
Diese Leistungslücke wird mit der nächsten Typoskript-Version fast verschwunden sein.

Ich weiß, dass ich es außer Kraft setzen kann, aber ich bin ziemlich stark davon überzeugt, dass die Empfehlung falsch ist.

Hier ist meine Sicht darauf. Es gibt viele Fälle, in denen eine Schnittstelle nicht für einen Typalias verwendet werden kann. Sie können eine Schnittstelle nur verwenden, um ein Objektliteral einzugeben. Wenn ich die empfohlenen Best Practices befolgen soll, dann werden in einer bestimmten Klassendatei, in der ich möglicherweise mehrere Typaliase habe, einige Typaliase und einige Schnittstellen sein. Jemand, der über diese Klasse stolpert, wird sich fragen, was zum Teufel los ist und ob ich beabsichtige, die Schnittstellen irgendwo zu implementieren/erweitern, oder zumindest erwarte, dass dies eine Möglichkeit ist.

Meiner Meinung nach wäre es viel sauberer für mich, einen Typ-Alias ​​für einen Typ-Alias ​​und eine Schnittstelle für eine Schnittstelle zu verwenden, anstatt in einigen Fällen einen durch den anderen zu ersetzen, nur weil Schnittstellen einige zusätzliche Fähigkeiten haben (die ich nicht brauche). wenn alles will, ist ein Typ-Alias).

Ich nehme an, ich sollte ein Problem gegen die Typoskript-Dokumentation schreiben, was ich tun werde, aber ich denke, dass hier ein technisches Urteil angewendet werden kann, anstatt eine Regel zu implementieren, nur weil die Dokumentation sagt, dass Sie es tun sollten.

Von der Verwendung des Interface-Schlüsselworts für Strukturen sollte meiner Meinung nach wirklich abgeraten werden. Diese Regel bewirkt genau das Gegenteil, daher kann dies auf keinen Fall als bewährte Methode angesehen werden.

Dies ist meiner Meinung nach eines der Dinge, die Typoskript falsch gemacht hat. Dies verwirrt das Konzept der Schnittstelle, deren Semantik in allen anderen typsicheren Sprachen, die ich verwendet habe, "eine Sammlung von Methoden / Funktionen / aufrufbaren Dingen" mit der Objektsignatur / bedeutet. Entenart. Die Verwendung von Schnittstellen sollte restriktiver sein, und ich würde eine TSLint-Regel „Schnittstelle muss nur Funktionen deklarieren“ oder eine weniger restriktive „Schnittstelle muss mindestens eine Funktion deklarieren“ sehr begrüßen.

Reine Strukturen sollten mit dem Typoperator deklariert und mit dem &-Operator erweitert werden. Und der Name sollte mit "T" beginnen :-)

@navels Ich stimme Ihrem Feedback zu, ich denke, tslint:recommended sollte diese übermäßig eigensinnige Regelkonfiguration als Breaking Change in der nächsten Hauptversion entfernen

Wie kann ich diese Option überschreiben?

@sibelius in Ihrem tslint.json unter "rules" markieren Sie es als false :

{
    "extends": ["tslint:recommended"],
    "rules": {
        "interface-over-type-literal": false
    }
}

Beachten Sie, dass dieses Problem darin besteht, die Regel im empfohlenen Regelsatz zu deaktivieren. Wenn Sie allgemeine Fragen zu TSLint haben, verwenden Sie bitte entweder StackOverflow oder Gitter.

Hier spricht jemand über dieses Thema https://medium.com/@martin_hotell/interface -vs-type-alias-in-typescript-2-7-2a8f1777af4c

Was das Überschreiben der Regel betrifft, würde ich die Option bevorzugen, mich zur Verwendung von Typ anstelle von Schnittstelle zu zwingen, oder noch besser, mich dazu zu zwingen, Typ nur zu verwenden, wenn ich in meiner Reaktion ein Props oder State definiere Komponente.

Ich habe immer weniger OOP-Code geschrieben, bis zu dem Punkt, dass ich ihn in meinem aktuellen Projekt überhaupt nicht mehr verwende.
Ich möchte nicht, dass Anfänger dazu angestupst werden.

@dandrei und ich verwende Schnittstellen nur, wenn ich Funktionen beschreiben möchte (ich verwende auch kein OOP).

Ja, das ist definitiv falsch und meiner Meinung nach sollte es nicht Teil der empfohlenen sein oder zumindest nicht automatisch behoben werden, damit wir es deaktivieren können, bevor es unsere Typen verprügelt.

Die Empfehlung bricht tatsächlich den Code. Erwägen:

type Foo = {
  foo: string
}

interface IndexedObject {
  [key: string]: string
}

function useIndexedObject(object: IndexedObject) {}

const foo: Foo = {foo: "foo"}
useIndexedObject(foo)

Der obige Code funktioniert. Bis tslint --fix angewendet wird und type Foo in interface Foo ändert, erzeugt die letzte Zeile den Fehler:

Argument of type 'Foo' is not assignable to parameter of type 'IndexedObject'.
  Index signature is missing in type 'Foo'.

IMO, jede Regel, die Code bricht, sollte keine Empfehlung sein. Verdammt, es sollte nicht einmal eine Regel sein, wenn es das Potenzial hat, Code zu brechen.

Nicht nur das, sondern es verursacht auch die Regel "Schnittstellen müssen mit 'I' beginnen".

error TS2344: ...
Index Signature is missing in type 'SOME INTERFACE'.

also muss ich type verwenden.

Wenn Ihre Apps viel type verwendet werden, ist dies ein guter Indikator für Verstöße gegen die SOLID-Prinzipien.

Entfernen des Labels Type: Breaking Change gemäß #4811. Akzeptiere jetzt PRs!

Warum heißt es also TypeScript, wenn es eigentlich InterfaceScript heißen sollte?! 🤣

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen