-
Notifications
You must be signed in to change notification settings - Fork 889
interface-over-type-literal shouldn't be recommended #3248
Comments
Sorry, I don't get what you mean. Is this a feature request or a bug report? |
The default value for interface-over-type-literal in recommended.ts is true. I believe it should be false. Not sure if that constitutes a feature request or a bug :-) |
After all the recommended preset is opinionated. It incorporates best practices and suggestions like the one you posted above. Anyways, disabling the rule would be a breaking change. So don't expect any change before the next major version. To clarify: 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 Since a type alias and an interface can be used (almost) interchangeably, I don't see why you would prefer the type alias. On a related note: interfaces used to be cached while anonymous types like type aliases were recomputed for ever usage. So using type aliases could significantly increase compile time. |
I do know that I can override it, but I feel pretty strongly that the recommendation is incorrect. Here's my view of it. There are many cases where an interface cannot be used for a type alias. You can only use an interface to type an object literal. If I am to follow the recommended best practices, then in a particular class file where I may have several type aliases, some will be type aliases and some will be interfaces. Someone stumbling upon this class will wonder what the heck is going on and if I am intending the interfaces to be implemented/extended somewhere, or to at least be expecting it to be a possibility. It would be much cleaner in my opinion for me to use a type alias for a type alias and an interface for an interface, rather than substitute one for the other in some cases just because interfaces have some extra capability (that I don't need if all want is a type alias). I suppose I should write up an issue against the typescript docs, which I will do, but I think some engineering judgement can be applied here rather than implement a rule just because the docs say you should. |
The use of interface keyword for structures should really be discouraged in my opinion. This rule does exactly the opposite, so there is no way in hell this can be considered a best practice. This is one of the things typescript got wrong in my opinion, this is confusing the concept of interface, whose semantics in all other typesafe languages I've used, means "a collection of methods/functions/callable things", with object signature/duck type. The use of interface should be more restrictive, and I would really welcome a TSLint rule "interface-must-declare-only-functions", or a less restrictive "interface-must-declare-at-least-one-function" Pure structures should be declared using the type operator and extended using the & operator. And the name should start with "T" :-) |
@navels I agree with your feedback, I think |
how can I override this option? |
@sibelius in your {
"extends": ["tslint:recommended"],
"rules": {
"interface-over-type-literal": false
}
} Note that this issue is tracking disabling the rule in the recommended ruleset. If you have general questions on TSLint, please use either StackOverflow or Gitter. |
Here someone talk about this subject https://medium.com/@martin_hotell/interface-vs-type-alias-in-typescript-2-7-2a8f1777af4c About overwrite the rule, I would prefer the option to force me use type instead of interface or even better, force me to use type only if I'm defining a |
I've been writing less and less OOP code to the point that I'm not using it at all in my current project. |
@dandrei and I use Interfaces only, when I want to describe functions (I use no OOP too). |
Yeah, this one's definitely wrong and IMO should not be part of the recommended, or at least not auto-fixed so we can disable it before it clobbers our types. |
The recommendation actually breaks code. Consider: type Foo = {
foo: string
}
interface IndexedObject {
[key: string]: string
}
function useIndexedObject(object: IndexedObject) {}
const foo: Foo = {foo: "foo"}
useIndexedObject(foo) The above code works. Until tslint --fix is applied and changes
IMO, any rule that breaks code should not be a recommendation. Heck, it shouldn't even be a rule if it has the potential to break code. |
Not only that, but it also causes the "interfaces must start with 'I'" rule. |
See palantir/tslint#3248 for details.
Argument here makese sense and is in milestone 6.0 going forward palantir/tslint#3248
so I have to use type. |
If your apps have a lot of |
Removing the |
So why is it called TypeScript, when it should be named InterfaceScript?! 🤣 |
Yes, I know the Typescript docs say
but seriously, if I am making a simple type with zero intention of ever using it as an extendable thing, it makes no sense to code it as an interface.
The text was updated successfully, but these errors were encountered: