类型安全的 Javascript

Posted

技术标签:

【中文标题】类型安全的 Javascript【英文标题】:Typesafe Javascript 【发布时间】:2011-10-26 09:39:54 【问题描述】:

有没有办法在 javascript 中强制执行类型?我正在考虑一个预处理器,它接受一个用 ActionScript 3 或 Java 编写的输入文件并将其转换为 JS。

我不需要一个大的运行时设备,我只需要在我的工作流程中引入编译时的概念,并对我的代码运行微不足道的编译时检查(并且还使用接口)。我不需要来自 Java 或 Flex 的 API,只需要语法。

也可以对照 IDL 定义检查标准浏览器功能,但这不是必须的。

【问题讨论】:

你所说的类型是指变量类型?因为使用typeof(variable) 很容易做到这一点。 您可以使用===!== 强制执行“类型安全相等检查”。 感谢您的想法,我知道可以手动检查 JS 中的类型,我只是不想这样做。 对于编译时类型验证,需要生成 JavaScript(因为 JavaScript 只允许您进行运行时检查)。这很可能成为大型 JavaScript 项目的常态。 【参考方案1】:

虽然我参加这个聚会有点晚了,但我认为绝对值得一提的是Dart(Google 产品)和TypeScript(Microsoft 产品)。

随着应用程序越来越基于 Web,JavaScript 正迅速成为一种非常流行的语言。但是,正如您所指出的,JavaScript 缺乏类型安全性,仅举几例;类、接口和包/命名空间/模块。

这就是 Dart 和 TypeScript 介入的地方。这些语言本质上是 JavaScript 的超集。当您编写 Dart 或 TypeScript 代码时,它会被编译成干净、符合标准的 JavaScript。

Dart 和 TypeScript 的优势在于它们提供类型安全、接口、类等。因此,您可以编写更清晰、可扩展、可管理的应用程序,这些应用程序仍可在浏览器中运行。

作为一名面向 Microsoft 的程序员,我在 TypeScript 方面拥有丰富的经验,包括积极参与该语言的开发(您可以在 codeplex 找到有关 TypeScript 开发的信息)

目前我唯一担心的是 TypeScript 缺少一些基本功能。当前的一些实现(0.9.0 alpha)似乎有一些同样巨大的漏洞,可能会阻止精明的开发人员目前使用它(当然可能会发生变化)。

我无法对 Dart 发表评论,因为我只使用过几次,但我对 Dart 的总体体验很好!

【讨论】:

【参考方案2】:

你应该看看haxe project。

Haxe 是一种非常好的类型化语言,它使用类型推断(即您不必编写大量类型声明),但在编译时强制类型正确性。

该语言具有类似 javascript 的语法,编译器可以为 neko 虚拟机、javascript、as3、c++ 或 php 生成代码。

更新

今天最流行的选择可能是Typescript,它是 Javascript 的超集,它允许在编译时强制执行可选类型声明。

【讨论】:

太棒了!这正是我梦寐以求的:)【参考方案3】:

GWT 可以满足您的需求,但在大多数情况下它的尺寸过大。你可以看看 googles closure 框架,它用anotations 伪造了打字保险箱

【讨论】:

谢谢,闭包绝对是朝着正确方向迈出的一步,但是作为一个 JS2JS 编译器,它迫使我使用那些超级笨拙的注释。我承认如果 JS 是唯一知道的语言,这很有用,但恕我直言,使用 Java 或 AS3 将是正确的方法【参考方案4】:

有许多静态类型语言的设计都是为了特定目标编译成JavaScript(所谓的汇编网络):

Flow 来自 Facebook

Dart 来自 Google

TypeScript 来自微软

JXS DeNA

【讨论】:

【参考方案5】:

虽然typeof 将为每个对象或数组返回'object',但您可以使用instanceof 语句。假设您有一个类Person,并且想查看传递给您的函数的对象是否是Person,您可以这样做:

function someFunc(person)
  if(! person instanceof Person)
    throw('argument needs to be an instance of Person.');

  /* ... do your stuff ... */

如果你只是想确保一个变量是数字 3 而不是字符串 '3',你只需要使用 === 而不是 ==

if( var === 3 )
  /* ... do your stuff ... */

【讨论】:

谢谢,但问题的关键是我希望这些事情自动化。使用=== 的开销并不大,但运行时检查仅在与单元测试结合使用时才有用,即使如此,也不能保证在测试期间对函数的每个调用都已运行。【参考方案6】:

我同意 Javascript 是一门漂亮的语言,但也有一些明显的漏洞,其中最糟糕且最不引人注目的是缺少静态类型安全。

正如 eskimoblood 所指出的,GWT 和 Closure 的形式有一些折中的方法,但 正确 答案是 imo,它是 Scala,它将 Javascript 的灵活性和表达能力与类型系统结合得非常好比 Java 更好——或者 是正确的答案,只是 Scala-GWT 项目似乎陷入了困境。

现在,我们等待......

【讨论】:

【参考方案7】:

Infernu 是 JavaScript 的类型安全子集。它不会编译成 JavaScript - 它可以在您的浏览器中按原样运行!类型检查器支持完整的类型推断,因此不需要类型注释(将来它们将支持文档和结构相同类型之间的故意区分)。它尚未准备好使用,但正在进行中。

【讨论】:

【参考方案8】:

这是一个用于 nodejs/浏览器的轻量级类型安全函数包装器:

https://www.npmjs.com/package/typeshave

它的 3.9K 压缩包,支持 jsonschema,几乎可以在任何地方使用。所以:

foo = function(bar)


可以这样改写:

foo = typesafe( 
  bar:  type: "object"  
, function(bar)


或者只是稍后包装,包括验证深层结构和可选参数:

foo = typesafe(
  bar:  
    type: "object", 
    required: true,
    properties: 
      foo:  type: "string", required:true ,
      items: [
        type: "integer"  
      ]
    
  
, foo ); 

foo( foo: "helloworld", items:[1,2,3] );

在 coffeescript imho 中看起来不那么嘈杂

【讨论】:

以上是关于类型安全的 Javascript的主要内容,如果未能解决你的问题,请参考以下文章

Java并发:五种线程安全类型线程安全的实现枚举类型

什么是类型安全?

Silverlight 中使用安全关键构造函数对透明类型进行子类化的安全规则

某些 Java 泛型类型转换中的类型安全警告是啥意思?

在 snap 中使用具有持久数据类型的类型安全路由

Kotlin空安全 ② ( 手动空安全管理 | 空安全调用操作符 ? | let 函数结合空安全调用操作符使用 )