JavaScript:我能以某种方式强类型函数参数吗

JavaScript: can I somehow strong type function parameters?

本文关键字:强类型 方式 函数 参数 JavaScript      更新时间:2023-09-26

我是JavaScript的新手,我觉得不可抗拒地需要为我正在编码的几个工具强键入我的函数参数:

  1. 这将使我能够自动完成这些功能
  2. 调试/功能访问更加一致

经过一些谷歌搜索,我想这是不可能的。然而,有没有通用的工具可以简单地模仿这一点?

你有什么想法?

人们写"你不应该使用它"是错误的。在下一个JavaScript2.x规范中,有一个添加强类型变量的计划。

同时,您可以使用非常简单的解决方案来模拟强类型:

var = Object.create( String );

在那之后,许多IDE(包括IntelliJ IDEA)中的自动完成将非常有效,并且您已经声明并初始化了指定类型的对象。

在我的博客上阅读更多。

不,你不能,即使有办法你也不应该。JavaScript是一种动态类型语言。然而,对于自动完成,您可以使用JSDoc风格的文档标记,这些标记提供一些类型指针:

var Person = {
    /**
     * Say hi
     * @param {String} name The name to say hi to
     * @return {String}
     */
    sayHi : function(name)
    {
        return 'Hi ' + name;
    }
}

不过,它们是否被使用完全取决于您的IDE。

你看过Typescript吗?这是微软的一个开源项目,允许您使用强类型进行开发,然后将代码编译成Javascript。我知道是微软,但在你解雇它之前先看看。

http://www.typescriptlang.org/


编辑2017

现在有两个大玩家在这个场景中,Typescript(如上所述)已经被战斗证明,现在被Angular 2广泛使用。如果结构和相当严格的打字如果你正在寻找什么,那是你最好的选择。

另一个选项是Flow(https://flow.org/)它是由Facebook开发的,在React中被他们大量使用。Flow只允许您指定要键入检查的文件,并且是输入IMO.的较低障碍

值得一提的是,添加类型检查会给您的构建过程增加相当大的复杂性——这需要您有一个构建过程!

您看过Google闭包编译器吗?

某些IDE(比如Jetbrains的产品)试图理解JSDoc并提供帮助,但有时它们的注释解析器与Google Closure的冲突。然而,即使使用Closure,你也不会得到完美的强类型。

此外,这可能有些过头了,但看看哈克。

JavaScript识别以下类型的值:

数字:例如42或3.14159

逻辑(布尔):值为true或false

字符串:例如"你好!"

null:表示null值的特殊关键字;null也是一个基元值。由于JavaScript区分大小写,null与null、null或任何其他变体不同

未定义:一个顶级属性,其值未定义;undefined也是一个基元值。

整数和实数之间没有明确的区别 […]

JavaScript是一种动态类型语言。这意味着您在声明变量时不必指定该变量的数据类型,并且在脚本执行过程中根据需要自动转换数据类型

发件人https://developer.mozilla.org/en/JavaScript/Guide/Values%2C_Variables%2C_and_Literals

因此,不,您不能在JavaScript 中使用强类型

您可以在函数中使用包装器来实现一个自动处理类型检查的系统

使用这种方法,您可以构建一个完整的declarative type check system,它将为您管理类型检查。如果你有兴趣更深入地了解这个概念,请查看Functyped库

以下实现以一种简单但可操作的方式说明了主要思想:

/*
 * checkType() : Test the type of the value. If succeds return true, 
 * if fails, throw an Error
 */
function checkType(value,type, i){
  // perform the appropiate test to the passed 
  // value according to the provided type
  switch(type){
    case Boolean : 
      if(typeof value === 'boolean') return true;
      break;
    case String : 
      if(typeof value === 'string') return true;
      break;
    case Number : 
      if(typeof value === 'number') return true;
      break;
    default :
      throw new Error(`TypeError : Unknown type provided in argument ${i+1}`);
  }
  // test didn't succeed , throw error
  throw new Error(`TypeError : Expecting a ${type.name} in argument ${i+1}`);
}
/*
 * typedFunction() : Constructor that returns a wrapper
 * to handle each function call, performing automatic 
 * arguments type checking
 */
function typedFunction( parameterTypes, func ){
  // types definitions and function parameters 
  // count must match
  if(parameterTypes.length !== func.length) throw new Error(`Function has ${func.length} arguments, but type definition has ${parameterTypes.length}`);
  // return the wrapper...
  return function(...args){
    // provided arguments count must match types
    // definitions count
    if(parameterTypes.length !== args.length) throw new Error(`Function expects ${func.length} arguments, instead ${args.length} found.`);
    // iterate each argument value, and perform a
    // type check against it, using the type definitions
    // provided in the construction stage
    for(let i=0; i<args.length;i++) checkType( args[i], parameterTypes[i] , i)
    // if no error has been thrown, type check succeed
    // execute function!
    return func(...args);
  }
}
// Play time! 
// Declare a function that expects 2 Numbers
let myFunc = typedFunction( [ Number, Number ],  (a,b)=>{
  return a+b;
});
// call the function, with an invalid second argument
myFunc(123, '456')
// ERROR! Uncaught Error: TypeError : Expecting a Number in argument 2

不,你不能;javascript是一种弱类型语言。这意味着JavaScript将计算出您拥有的数据类型。

您应该考虑在谷歌闭包编译器中使用"ADVANCED_OPTIMIZATIONS"来编译您的工作,该编译器将对您的参数或变量进行类型检查。

闭包编译器的JavaScript注释:类型表达式

示例数据类型:boolean、Window、goog.ui.Menu、string、number

下面是一个声明变量及其数据类型的示例。如果您试图将变量设置为另一种数据类型,它将在编译后显示错误或警告消息。

/**
 * The message hex ID.
 * @type {string}
 */
var hexId = hexId;

下面是一个带有可能参数类型的类声明示例:

/**
 * Some class, initialized with an optional value.
 * @param {Object=} opt_value Some value (optional).
 * @constructor
 */
function MyClass(opt_value) {
  /**
   * Some value.
   * @type {Object|undefined}
   */
  this.myValue = opt_value;
}

使用"ADVANCED_OPTIMIZATIONS"可以使您更正确地编写JavaScript,因为它还提供了一些链接