我无法确定何时,如果有的话,你想要使用类型而不是接口来为typescript中的变量.假设以下两个:
type User = { id: string; name: string; type: string; } interface User { id: string; name: string; type: string; }
我可以定义一个与const用户完全相同的变量:User = ….但是,这里是我可以用接口做的所有事情,我不能用类型做:
// Extension: interface AdminUser extends User { permissions: string[]; role: string; } // Using in abstract method: abstract class Home { abstract login(user: User): void; } class AdminHome extends Home { login(user: AdminUser) { ... } }
仅举几个.
所以我的问题是:你什么时候想要使用某种类型?
解决方法
在OOP术语中,接口没有实现.类型做.因此,除非类型实现它,否则接口基本上是无用的.此外,类型只能扩展另一种类型.但它可以实现许多接口.
但这是什么意思……
假设你有一辆车和一个用户.非常不同的类型,你不会立即认为是以任何实际的方式相同.有些人可能会说,“好吧,你应该创造ICar和IUser”.但实际上,这不是考虑接口的实用方法.用户实施ICar会很困惑,和/或,ICar似乎和Car一样.与另一个看代码的程序员有什么区别?
假设你想要它们(再次只是为了它),“Self Describable”,你希望它们都以相同的方式提供信息.所以你要创造:
ISelfDescribable { getSelfDescription ( ); }
现在,你要这样做:
Car implements ISelfDescribable { getSelfDescription ( return "I am a car!" ); } User implements ISelfDescribable { getSelfDescription ( return ...some other completely different way of getting the info... ); }
这些对象的数组将是(想想如果没有接口你将如何做到这一点):
Array<ISelfDescribable>
现在,您(以及任何其他查看代码的开发人员)知道一个事实,此数组中的任何对象,无论具体类型如何,都实现了ISelfDesribable的“行为”.如果你考虑一下,除非你正在实施它,否则根本不需要知道什么是类型,你只关心行为.但是你仍然需要这种类型来实现这种行为.
假设有一天你想要这两个对象都是“可保险的”.他们都应该有一个方法,“setInsurancePolicy”.您可以创建IInsurable {setInsurancePolicy(policy:Policy)},并在类型中实现它.现在您拥有ISelfDescribable和IInsurable的对象,并且您可以将这些对象的数组键入为任一对象.
所以对我来说,当我开始思考时,大灯泡就会消失:类型(和类型层次结构)应该与具体事物有关.接口应该关注可以在不同类型之间共享的行为.还有更多,但至少给出了为什么选择接口或类型的概念.它们在编程方面代表不同的东西,即使它们看起来是相同的.
(附录:像Scala这样的语言不会以这种方式来考虑界面.他们确实有“行为”的概念,但你也可以实现行为,并覆盖它们.对于这个特定的问题,这可能是太多的学术问题,但是,嘿,我需要杀死地牢中的所有怪物,而不仅仅是那个任务中的怪物.