为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

元芳怎么了 2021-05-10 17:01:19
我在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既可以肯定又可以签订合同?
查看完整描述

2 回答

?
德玛西亚99

TA贡献1770条经验 获得超3个赞

我对肯定和可组合性也不是很熟悉,但是我认为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。


查看完整回答
反对 回复 2021-05-13
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我对您的意思不是很熟悉,“有什么方法可以使Flow产生积极的和可组合的合同吗?” (我假设这是来自另一种语言吗?),并且我还没有按照您描述的方式使用流程;这是将函数定义定义为类型的一部分,但我希望这里的方法会对您有所帮助。


我在这里要做的第一件事是为 MaybeUnit


export type MaybeUnit = Unit &{

  isMaybe: (obj): boolean

};

但是,我再一次不熟悉该函数是否属于该类型。每当我想要一个函数时,我都会定义一个类(可能带有interface)而不是类型。这可能会将您的实现更改为如下所示:


interface IUnit {

  of(value: any): Monad;

}


class Unit implements IUnit {

  of(value): Monad { 

    return new Monad();

  }

}


interface IMaybeUnit extends IUnit {

  isMaybe({}): boolean;

}


class MaybeUnit extends Unit implements IMaybeUnit {

  isMaybe({}): boolean { 

    return true;

  }

}

希望这种方法可以解决您的问题。


更新:添加一个示例,说明我有时对管理器类所做的事情。这是一种非常冗长的方法,并且仅在某些情况下适用。当使用流运行时以便在执行时而不是在构建时测试类型时,它也更加有用。


class UnitManager {


  static UnitTypes:Map<string, IUnit>;


  static RegisterUnitType( key:string, klass:Class ) {

    UnitManager.UnitTypes.set( key, klass );

  }


  static CreateUnit( unit:IUnit ):Unit {

    // test data to determine type

    let type:string = UnitManager.GetUnitType( unit );

    let klass:Class = UnitManager.UnitTypes.get( type );

    return new klass( unit );

  }


  static GetUnitType( unit:IUnit ):IUnit {

    // 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.

  }

}

一开始我没有包括它,因为它不是很干净,并且通常会是反模式。在某些情况下这很有用,我发现自己主要是为了避免循环依赖。


有时我会这样做,以便每个类的构造函数根据其类中的静态“名称”常量向管理器注册自己。


查看完整回答
反对 回复 2021-05-13
  • 2 回答
  • 0 关注
  • 147 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信