如何在 运行 时在 JavaScript 中生成类型检查?

How to generate type checking in JavaScript at run time?

使用 TypeScript 或 Facebook 的 Flow(type) 我可以静态键入变量,例如

function add (x: integer, y: integer) { ... }

TypeScript 和 Flow 都会在 编译时 捕获任何非法调用,例如 add('1',0)

但是,当库被编译和导出时,类型没有了。这意味着,使用该函数的库使用者不会出错,这可能会导致难以调试的问题。

有什么方法可以自动生成在 运行 时抛出完全相同错误的附加代码吗?

每次需要进行类型检查时,我当然可以手动放置守卫,但这感觉很无聊和重复。

无论您选择哪个,您都不会单独从 javascript 获得它,因为 javascript 在这个意义上没有类型的概念。

我从来没有使用过 fb flow,所以我无法对此做出答复,但是在打字稿方面,我认为您可以选择以下选项:(按照复杂程度和没有意义的程度排序)

  1. 修改typescript编译器自动添加运行时参数验证
    您可以 use the compiler API 并注入一段代码来验证函数的参数。编译器会告诉你参数名称和类型是什么,如果它们是可选的等等。
    我只是把它作为一个选项包括在内,但在我看来这是一个非常混乱的解决方案。

  2. 启动每个函数并进行验证
    与上一个非常相似,只是您将自己将代码包含在每个函数中,而不是修改编译器来这样做。
    您可以拥有一个全局函数,它将声明的参数的元数据和传递的实际参数作为参数。
    这会使代码变得非常丑陋,而且维护起来也没有乐趣。

  3. 如果是 类 你可以使用装饰器
    The decorators feature 很新,但 typescript 允许您使用它,如果您想在 类 上执行此验证操作,那么这是迄今为止解决您的问题的最佳解决方案。

  4. 为你的库生成一个定义文件
    如果你问我,这是最好的选择。
    您不需要通过检查每个函数来污染您的代码。更重要的是,您永远无法控制谁在使用您的库或他们如何使用它,因此甚至没有理由尝试。
    为此,您的 lib 用户需要自己用 typescript 编写。

https://github.com/codemix/babel-plugin-typecheck做你想做的。

还有https://gcanti.github.io/flowcheck/不过看起来有点废弃

我个人没有使用过任何这些库。看起来它们可能涵盖不到 100% 的 Flow 语法。

你也可以尝试babel-plugin-runtyper在运行时执行类型检查,不需要手动注释。
对于您的示例,如果函数如下所示:

function add(x, y) {
   return x + y;
}

你称它为

add('1', 0);

您将在控制台中收到警告:

Plus operation with different types: "1" (string) + 0 (number)