【问题标题】:How to use List, Map, etc. from TypeScript如何使用 TypeScript 中的 List、Map 等
【发布时间】:2021-09-01 17:16:08
【问题描述】:

我有一个 ReScript 和 TypeScript 组合项目。我想使用 gentype 来公开 TypeScript 友好的对象。 Gentype 适用于字符串、布尔值、记录和其他基本对象,没有任何麻烦。如何使用 TypeScript 中的 listchar 以及其他特定于 ReScript 的类型?

有一个 shims 功能,但我不知道该怎么做。我会假设标准带库有内置垫片,但找不到它们。

我计划在 Rescript 中进行大部分计算和繁重的工作。所以当信息被发送到 TypeScript 时,我可能只是在消费数据,而不是修改它。这可能是遍历列表以显示非 Rescript React 项目中的内容。我不打算操纵数据。

一种选择是在导出结果之前在 ReScript 中将列表转换为数组。因此,任何时候我想使用来自 TypeScript 的信息时,我都会在 ReScript 中创建一个函数和/或类型,它只有布尔、数字、字符串、数组和对象。我可以创建一个“互操作”模块,其中包含我想从 TypeScript 使用或使用的所有东西。这提供了 ReScript 和 TypeScript 世界之间的清晰分离,并且很容易让我理解,但似乎效率有点低(比如将所有列表转换为数组)和额外的工作。

另一方面,如果在 TypeScript 中使用诸如 list 和 map 之类的 Belt 对象很麻烦,即使使用了 shims,那么我最好还是创建我的“互操作”模块。

在 TypeScript 中使用 list、map、char 和其他 ReScript 特定对象的推荐/最简单/最佳方式是什么?是否有针对 Belt 标准库的友好 Typescript 定义,即使我不使用 ReScript 也可以使用?

===

一个附加说明。我有尝试从 C# 使用 F#(功能)的经验。这很痛苦。在那种环境下,对我来说最好的解决方案是在 F# 端创建一个接口,该接口在不使用 F# 本机对象的 C# 端很容易使用。

【问题讨论】:

    标签: interop rescript


    【解决方案1】:

    由于 rescript 编译为 JavaScript,并且输出非常易读且(通常)直截了当,您可以模拟它生成的内容。

    例如这个rescript代码:

    let xs = list{1, 2, 3}
    let _ = List.map(x => x + 1, xs)
    

    被编译成这个(稍微简化的)JavaScript:

    var List = require("./stdlib/list.js");
    
    var xs = {
      hd: 1,
      tl: {
        hd: 2,
        tl: {
          hd: 3,
          tl: /* [] */0
        }
      }
    };
    
    List.map((x) => x + 1, xs);
    

    列表的文字语法有一个小问题,但可以通过使用List.cons 来简化一点:

    let xs = List.cons(1, List.cons(2, List.cons(3, list{})))
    

    变成:

    var xs = List.cons(1, List.cons(2, List.cons(3, /* [] */0)));
    

    显然,模式匹配也不那么方便,但至少对于简单的事情来说仍然非常简单。例如:

    let rec sum = xs => switch xs {
      | list{} => 0
      | list{x, ...rest} => x + sum(rest)
    }
    

    变成:

    function sum(xs) {
      if (xs) {
        return xs.hd + sum(xs.tl);
      } else {
        return 0;
      }
    }
    

    大多数其他类型没有任何特殊的编译器支持,因此只是普通的函数调用。以Belt.Map 为例,尽管使用了一些高级语言特性,但编译为非常直接的 JavaScript:

    module IntCmp = Belt.Id.MakeComparable({
      type t = int
      let cmp = (a, b) => a - b
    })
    
    let m = Belt.Map.make(~id=module(IntCmp))
    let _ = Belt.Map.set(m, 0, "a")
    

    变成(或多或少):

    var Belt_Id = require("./stdlib/belt_Id.js");
    var Belt_Map = require("./stdlib/belt_Map.js");
    
    var IntCmp = Belt_Id.MakeComparable({
          cmp: (a, b) => a - b
        });
    
    var m = Belt_Map.make(IntCmp);
    Belt_Map.set(m, 0, "a");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-14
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-26
      • 1970-01-01
      相关资源
      最近更新 更多