如何声明具有相同主体的 2 个接口?

Posted

技术标签:

【中文标题】如何声明具有相同主体的 2 个接口?【英文标题】:How to declare 2 interfaces with the same body? 【发布时间】:2022-01-03 16:32:25 【问题描述】:

我有一个基本接口 IInput 并从它扩展了 3 个接口 IType1InputIType2InputIType3Input。在对Type2() 进行一些业务更改后,IType2Input 现在与IInput 相同,但为了保持一致性,我不希望仅Type2() 使用IInput 而不是扩展接口。我试着这样做:

    interface IType2Input extends IInput 

ESLint 然后警告我no-empty-interface。如果我不想禁用此规则,有没有办法将IType2Input 声明为与IInput 相同的接口?

【问题讨论】:

"如果我不想禁用此规则"... 你不能只用disable the rule for one line 吗?既然您打算创建一个与现有界面相同的新界面,那么您确实想打破规则,对吧?而不是以某种方式规避规则,为什么不只是 proudly admit 在这种情况下该规则对您没有帮助,并且您想要 IInput 的空扩展名,并且您有充分的理由想要这个。您可以尝试使用this 之类的方法来规避规则,但为什么呢? 如果它满足您的需求,我很乐意将其写成答案。如果没有,您能否edit您的问题进一步解释动机? @jcalz 我只是想知道是否真的可以以某种不错的方式为一个接口声明 2 个名称,或 2 个具有相同主体的接口; switch 中的 1 个主体类似于多个 cases。如果不可能,那么我将禁用 ESLint 规则。我之所以设置“如果我不想禁用此规则”,是为了防止人们沿着这条线提出答案,我已经知道这是一个选项。 我只是想确保我们在同一页面上:您知道您可以仅针对一行而不是完全禁用该规则,对吧? 我要睡觉了,但我可能会在明天写一个答案。 【参考方案1】:

尝试使用类型而不是接口,直到该接口不同为止。请注意,底层接口和类型是相同的。

type IType2Input = IInput;

【讨论】:

“引擎盖下的接口和类型是相同的” interfaces and type aliases to object types are observably not the same. 我的意思是,当它们被转译为 javascript 时,它们基本上是相同的。确实,它们的定义和使用方式存在一些差异(如此处***.com/questions/37233735/… 所述),但在底层它们几乎相同。 "当它们被转译为 javascript 时,它们基本上是相同的" 静态类型系统是 erased 完全来自发出的 JavaScript ......所以是的,我猜,它们在尊重,但你也会说 interface Foo a: stringinterface Bar a: number 那样“相同”,这不是你的意思,对吧? 没错:) 我不明白,可能是因为我的问题是否定的。你是说interface Foo a: stringinterface Bar a: number“在底层是一样的”?【参考方案2】:

我知道您不是在寻找此建议,因此请随意跳过以下部分。这主要适用于遇到此问题/答案对的未来读者。


我想说the no-empty-interface ESLint rule 不适合您的用例,您确实应该disable the rule for the line in question 而不必为您的整个代码库禁用它。

该规则的文档说“一个空接口等同于它的超类型...... [因此它] 可以被省略。”当你写

interface IType2Input extends IInput  // linter warning!

并得到一个 linter 警告,该规则希望您将所有对 IType2Input 的引用替换为 IInput,因为 IType2Input 是多余的。但你不想这样做。如果您找到一种方法来重写您的代码,以便在不触发 linter 警告的情况下存在名为 IType2InputIInput 的两个等效接口,那么即使不是字母,您仍然违反了规则的精神。

与其试图弄清楚如何使用可能比空接口更复杂的语法来规避规则,您可以只禁用一个声明的规则,并对其进行注释以让人们知道您在做什么为什么:

// IType2Input is intentionally empty. It happens not
// to have more properties than IInput, but this may
// change in the future, and it helps to have a Type2-specific
// interface that people can use.  Therefore the no-empty-interface
// rule is not appropriate for this declaration:

// eslint-disable-next-line no-empty-interface
interface IType2Input extends IInput  

从这里开始,我假设你不想这样做。


规避规则的一种方法是使用extending 多个接口的语法,但“多个”接口都只是IInput

interface IType2Input extends IInput, IInput   // no error

这设法不触发 linter 规则。但是,正如你所说,它基本上是一个黑客。以后看到此代码的任何人都可能会将其重构为 extends IInput,这会使您回到最初的问题。


Playground link to code

【讨论】:

以上是关于如何声明具有相同主体的 2 个接口?的主要内容,如果未能解决你的问题,请参考以下文章

如何声明多个具有相同值的变量

可以在没有主体的情况下调用声明的函数

在 Hibernate 中映射 2 个具有相同结构的表

如何在 C# 中声明具有动态参数的函数 [重复]

具有相同参数的 Javascript 函数声明

如何处理具有相同实体 ID 的两个 IDP