-
-
Notifications
You must be signed in to change notification settings - Fork 498
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
💅 lint/suspicious/noEmptyInterface false positive #1157
Comments
|
What's your point? Type alias is not the same than an interface. |
We implemented the same behavior as the TypeScript Eslint rule no-empty-interface. Why a type alias doesn't fit your use-case? |
We try to always use interfaces cf https://typescript-eslint.io/rules/consistent-type-definitions |
Performance? Are you aware that Moreover, I think that an empty interface that extends a type is non-idiomatic TypeScript code. Even the TypeScript team that advocates the use of interfaces, resort to type aliases for this kind of thing. |
You can have a look at this: https://github.com/microsoft/TypeScript/wiki/Performance#preferring-interfaces-over-intersections |
Thanks for sharing this resource! They recommend using interfaces that extend two or more types instead of using type intersections. Thus, this doesn't apply to empty interfaces that extend a single type. Although not explicitly said, I think the TypeScript team recommend using type aliases instead of interfaces when the interface is empty and extends a single type. This is why the TypeScript ESLint rule If you are always using interfaces over type aliases, I think you should disable the |
Another case where you must use an interface: When you need to augment an interface. With the infamous JQuery as an example: declare global {
interface JQuery extends JQueryFunctionExtensionsMyAwesomePlugin {}
} The linter would rewrite the above as declare global {
type JQuery = JQueryFunctionExtensionsMyAwesomePlugin;
} which does not augment the module, and is also a compile error. ( Or a self contained example: interface Foobar {
foo: () => void;
bar: () => void;
}
interface Baz {
baz: () => void;
}
interface Foobar extends Baz {} Replacing the last last line with |
@blutorange I opened #1243 to allow empty interfaces that extend a type in global declarations. |
@Conaclos That sounds like a good idea, and should fix that use case, thanks for the PR : ) Out of curiosity, how do you feel about allowing empty interfaces that extend something in general, not only in module / global declarations? Code such as this is possible, albeit I'd hope less common (personally I don't think I'd need it): interface Foo {
x: () => void;
}
interface Bar {
y: () => void;
}
interface Baz {
z: () => void;
}
interface Foo extends Bar {} One could argue that the interface is not empty when properties are pulled in via // lint error (why do I have to change this to "type Foo = Bar" ?)
interface Foo extends Bar {}
// no lint error (why do I not have to change this to "type Foo = Bar & Baz" ?)
interface Foo extends Bar, Baz {} |
Yes, I have thought about this change. However, I am a bit hesitant about it because it will be a divergence from TypeScript ESLint. We could wait a bit to get more feedback. |
I think the (not obvious) choice between type/interface should be handled by Some other interesting content: |
The rule is now ignoring interfaces that extend a type. Thanks for your valuable comments! |
Environment information
Rule name
lint/suspicious/noEmptyInterface
Playground link
https://biomejs.dev/playground/?lintRules=all&code=aQBuAHQAZQByAGYAYQBjAGUAIABCACAAewAKACAAIABhADoAIABiAG8AbwBsAGUAYQBuACwACgAgACAAYgA6ACAAYgBvAG8AbABlAGEAbgAsAAoAfQAKAGkAbgB0AGUAcgBmAGEAYwBlACAAQQAgAGUAeAB0AGUAbgBkAHMAIABQAGkAYwBrADwAQgAsACAAJwBhACcAPgAgAHsAfQA%3D
Expected result
Should not report an error when extending something since the result is not an empty interface.
Code of Conduct
The text was updated successfully, but these errors were encountered: