Flow中的可组合合同和正合同

我在Flow中遇到问题,其中一个给定的实现type通过要求我仅使用在上声明的属性来限制我的对象API,type而不是要求我声明所有type的属性。


我是Flow的新手,所以我可能会犯一些基本的错误和错误。无论如何,我有这样的type声明:


type Unit = {

  of(value: any): Monad,

};

我在这里要说的是:根据实现的所有对象都Unit必须具有一个#of接收给定value并返回Monad-type值的方法。


当我在工厂实施它时,没有出现问题:


const Maybe: Unit = {

    isMaybe: (obj): boolean => { ... },

    of: (value): Monad => { ... },

};

但是,当我尝试致电时#isMaybe,出现了这个错误(在linter上):


flow(0|2), isMaybe (Cannot call: `Maybe.isMaybe` because property `isMaybe` is missing in `Unit` [1].)

现在,我尝试声明#isMaybe,Unit并且错误按预期消失了。问题是,Unit应该是一种自由接口,该接口检查其实现是否具有Unit属性,而不仅仅是 Unit属性。


我无法将-至少不是我所知道的-Unit从a重构type为a,interface因为我是通过is-a关系来构成它们的:


type Monad = Applicative & Chain; // Monad is-a Applicative and a Chain

有没有什么方法可以使Flow既可以肯定又可以签订合同?


元芳怎么了
浏览 148回答 2
2回答

德玛西亚99

我对肯定和可组合性也不是很熟悉,但是我认为interfaces可以帮助解决问题。您可以轻松扩展aninterface并将一个变量声明为one。请查看以下示例,以了解如何使用和扩展接口。请注意,在这种特殊情况下,无需遍历所有类。type Monad = any;interface Unit {  of(value: any): Monad;}const unit: Unit = {  of(value: any): Monad {    return value;  }}const notUnit: Unit = {};const alsoNotUnit: Unit = {  isMaybe(value: any): boolean {    return false;  }}interface Maybe extends Unit {  isMaybe(value: any): boolean;}const maybe: Maybe = {  isMaybe(value: any): boolean {    return true;  },  of(value: any): Monad {    return value;  }}const notMaybe: Maybe = {  isMaybe(value: any): boolean {    return true;  }};const alsoNotMaybe: Maybe = {  of(value: any): Monad {    return value;  }}试流提醒您一点,因为我看到您使用了&交集类型运算符-交集类型当前在Flow中是断开的并且不一致。我建议暂时不使用它们。它们的大多数行为都可以通过其他更正确的方法来完成,例如散布算子或extends。

小怪兽爱吃肉

我对您的意思不是很熟悉,“有什么方法可以使Flow产生积极的和可组合的合同吗?” (我假设这是来自另一种语言吗?),并且我还没有按照您描述的方式使用流程;这是将函数定义定义为类型的一部分,但我希望这里的方法会对您有所帮助。我在这里要做的第一件事是为 MaybeUnitexport type MaybeUnit = Unit &{&nbsp; isMaybe: (obj): boolean};但是,我再一次不熟悉该函数是否属于该类型。每当我想要一个函数时,我都会定义一个类(可能带有interface)而不是类型。这可能会将您的实现更改为如下所示:interface IUnit {&nbsp; of(value: any): Monad;}class Unit implements IUnit {&nbsp; of(value): Monad {&nbsp;&nbsp; &nbsp; return new Monad();&nbsp; }}interface IMaybeUnit extends IUnit {&nbsp; isMaybe({}): boolean;}class MaybeUnit extends Unit implements IMaybeUnit {&nbsp; isMaybe({}): boolean {&nbsp;&nbsp; &nbsp; return true;&nbsp; }}希望这种方法可以解决您的问题。更新:添加一个示例,说明我有时对管理器类所做的事情。这是一种非常冗长的方法,并且仅在某些情况下适用。当使用流运行时以便在执行时而不是在构建时测试类型时,它也更加有用。class UnitManager {&nbsp; static UnitTypes:Map<string, IUnit>;&nbsp; static RegisterUnitType( key:string, klass:Class ) {&nbsp; &nbsp; UnitManager.UnitTypes.set( key, klass );&nbsp; }&nbsp; static CreateUnit( unit:IUnit ):Unit {&nbsp; &nbsp; // test data to determine type&nbsp; &nbsp; let type:string = UnitManager.GetUnitType( unit );&nbsp; &nbsp; let klass:Class = UnitManager.UnitTypes.get( type );&nbsp; &nbsp; return new klass( unit );&nbsp; }&nbsp; static GetUnitType( unit:IUnit ):IUnit {&nbsp; &nbsp; // Magic. Your logic to determine the type based on the data provided. if you use flow-runtime, you can use instanceOf, otherwise I think you need to test if the keys exist in the data, or something.&nbsp; }}一开始我没有包括它,因为它不是很干净,并且通常会是反模式。在某些情况下这很有用,我发现自己主要是为了避免循环依赖。有时我会这样做,以便每个类的构造函数根据其类中的静态“名称”常量向管理器注册自己。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript