Tslint: interface-over-type-literal ne devrait pas être recommandé

Créé le 25 sept. 2017  ·  18Commentaires  ·  Source: palantir/tslint

Oui, je sais que les documents Typescript disent

Étant donné qu'une propriété idéale d'un logiciel est d'être ouvert à l'extension, vous devez toujours utiliser une interface sur un alias de type si possible.

mais sérieusement, si je crée un type simple sans aucune intention de l'utiliser comme une chose extensible, cela n'a aucun sens de le coder comme une interface.

API Breaking Change Enhancement

Commentaire le plus utile

Je sais que je peux passer outre, mais j'ai le sentiment assez fort que la recommandation est incorrecte.

Voici mon point de vue. Il existe de nombreux cas où une interface ne peut pas être utilisée pour un alias de type. Vous ne pouvez utiliser une interface que pour saisir un littéral d'objet. Si je dois suivre les meilleures pratiques recommandées, alors dans un fichier de classe particulier où je peux avoir plusieurs alias de type, certains seront des alias de type et d'autres des interfaces. Quelqu'un qui tombe sur cette classe se demandera ce qui se passe et si j'ai l'intention que les interfaces soient implémentées/étendues quelque part, ou du moins s'attendent à ce que ce soit une possibilité.

Ce serait beaucoup plus propre à mon avis pour moi d'utiliser un alias de type pour un alias de type et une interface pour une interface, plutôt que de remplacer l'un par l'autre dans certains cas simplement parce que les interfaces ont des capacités supplémentaires (dont je n'ai pas besoin si tout ce que vous voulez est un alias de type).

Je suppose que je devrais écrire un problème contre les documents dactylographiés, ce que je ferai, mais je pense qu'un jugement d'ingénierie peut être appliqué ici plutôt que de mettre en œuvre une règle simplement parce que les documents disent que vous devriez.

Tous les 18 commentaires

Désolé, je ne comprends pas ce que vous voulez dire. S'agit-il d'une demande de fonctionnalité ou d'un rapport de bogue ?

La valeur par défaut pour interface-over-type-literal dans recommend.ts est true. Je pense que ça doit être faux. Je ne sais pas si cela constitue une demande de fonctionnalité ou un bogue :-)

Après tout, le préréglage recommandé est opiniâtre. Il intègre les meilleures pratiques et suggestions comme celle que vous avez publiée ci-dessus.
Lors de l'extension d'un préréglage, vous pouvez ignorer la recommandation et adapter la configuration à vos besoins.

Quoi qu'il en soit, désactiver la règle serait un changement radical. Ne vous attendez donc à aucun changement avant la prochaine version majeure.


Pour clarifier : interface-over-type-literal ne se plaint que des déclarations d'alias de type.

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

Puisqu'un alias de type et une interface peuvent être utilisés (presque) de manière interchangeable, je ne vois pas pourquoi vous préféreriez l'alias de type.

Sur une note connexe : les interfaces étaient mises en cache tandis que les types anonymes tels que les alias de type étaient recalculés pour une utilisation permanente. Ainsi, l'utilisation d'alias de type pourrait augmenter considérablement le temps de compilation.
Cet écart de performances aura presque disparu avec la prochaine version dactylographiée.

Je sais que je peux passer outre, mais j'ai le sentiment assez fort que la recommandation est incorrecte.

Voici mon point de vue. Il existe de nombreux cas où une interface ne peut pas être utilisée pour un alias de type. Vous ne pouvez utiliser une interface que pour saisir un littéral d'objet. Si je dois suivre les meilleures pratiques recommandées, alors dans un fichier de classe particulier où je peux avoir plusieurs alias de type, certains seront des alias de type et d'autres des interfaces. Quelqu'un qui tombe sur cette classe se demandera ce qui se passe et si j'ai l'intention que les interfaces soient implémentées/étendues quelque part, ou du moins s'attendent à ce que ce soit une possibilité.

Ce serait beaucoup plus propre à mon avis pour moi d'utiliser un alias de type pour un alias de type et une interface pour une interface, plutôt que de remplacer l'un par l'autre dans certains cas simplement parce que les interfaces ont des capacités supplémentaires (dont je n'ai pas besoin si tout ce que vous voulez est un alias de type).

Je suppose que je devrais écrire un problème contre les documents dactylographiés, ce que je ferai, mais je pense qu'un jugement d'ingénierie peut être appliqué ici plutôt que de mettre en œuvre une règle simplement parce que les documents disent que vous devriez.

L'utilisation du mot-clé d'interface pour les structures devrait vraiment être découragée à mon avis. Cette règle fait exactement le contraire, il n'y a donc aucun moyen que cela puisse être considéré comme une meilleure pratique.

C'est l'une des choses que le tapuscrit s'est trompé à mon avis, c'est confondre le concept d'interface, dont la sémantique dans tous les autres langages de type sécurisé que j'ai utilisés, signifie "une collection de méthodes/fonctions/choses appelables", avec signature d'objet/ genre canard. L'utilisation de l'interface devrait être plus restrictive, et j'apprécierais vraiment une règle TSLint "interface-must-declare-only-functions", ou une "interface-must-declare-at-moins-une-fonction" moins restrictive

Les structures pures doivent être déclarées à l'aide de l'opérateur de type et étendues à l'aide de l'opérateur &. Et le nom devrait commencer par "T" :-)

@navels Je suis d'accord avec vos commentaires, je pense que tslint:recommended devrait supprimer cette configuration de règle trop opiniâtre en tant que changement de rupture dans la prochaine version majeure

comment puis-je remplacer cette option ?

@sibelius dans votre tslint.json , sous "rules" , marquez-le comme false :

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

Notez que ce problème suit la désactivation de la règle dans l'ensemble de règles recommandé. Si vous avez des questions générales sur TSLint, veuillez utiliser StackOverflow ou Gitter.

Ici, quelqu'un parle de ce sujet https://medium.com/@martin_hotell/interface -vs-type-alias-in-typescript-2-7-2a8f1777af4c

À propos d'écraser la règle, je préférerais l'option pour me forcer à utiliser le type au lieu de l'interface ou mieux encore, me forcer à utiliser le type uniquement si je définis un Props ou State dans ma réaction composant.

J'écris de moins en moins de code POO au point que je ne l'utilise plus du tout dans mon projet actuel.
Je ne voudrais pas que les débutants soient poussés vers cela.

@dandrei et moi n'utilisons que des interfaces lorsque je veux décrire des fonctions (je n'utilise pas non plus de POO).

Ouais, celui-ci est définitivement faux et IMO ne devrait pas faire partie des recommandations, ou du moins pas être corrigé automatiquement afin que nous puissions le désactiver avant qu'il n'encombre nos types.

La recommandation casse en fait le code. Considérer:

type Foo = {
  foo: string
}

interface IndexedObject {
  [key: string]: string
}

function useIndexedObject(object: IndexedObject) {}

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

Le code ci-dessus fonctionne. Jusqu'à ce que tslint --fix soit appliqué et change type Foo en interface Foo , la dernière ligne produit l'erreur :

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

IMO, toute règle qui enfreint le code ne devrait pas être une recommandation. Heck, cela ne devrait même pas être une règle si cela a le potentiel de casser le code.

Non seulement cela, mais cela provoque également la règle "les interfaces doivent commencer par 'I'".

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

donc je dois utiliser type .

Si vos applications ont beaucoup d'utilisation de type , c'est un bon indicateur de violation des principes SOLID.

Suppression de l'étiquette Type: Breaking Change par #4811. Accepte maintenant les PR !

Alors pourquoi s'appelle-t-il TypeScript, alors qu'il devrait s'appeler InterfaceScript ? ! 🤣

Cette page vous a été utile?
0 / 5 - 0 notes