设置功能参数的类型?

时间:2011-12-06 22:13:53

标签: javascript function

有没有办法让javascript函数知道某个参数属于某种类型?

能够做这样的事情是完美的:

function myFunction(Date myDate, String myString)
{
    //do stuff
}

谢谢!

更新:如果我想将myDate视为日期(为了在其上调用日期函数),答案是响亮的“不”,我有将它作为日期转换为函数或设置一个Date类型的新变量吗?

14 个答案:

答案 0 :(得分:127)

不,JavaScript不是静态类型语言。有时您可能需要手动检查函数体中的参数类型。

答案 1 :(得分:66)

不是自己的javascript,而是使用Google Closure Compiler高级模式,你可以这样做:

/**
 * @param {Date} myDate The date
 * @param {string} myString The string
 */
function myFunction(myDate, myString)
{
    //do stuff
}

请参阅http://code.google.com/closure/compiler/docs/js-for-compiler.html

答案 2 :(得分:44)

虽然您无法通知JavaScript 关于类型的语言,但您可以通知您的IDE,这样您就可以获得更多有用的自动完成功能。为此,请通过在/* comment */

中指定参数之前的类型来使用类型提示

enter image description here

这是一种非常普遍的技术,例如使用by ReactJS。非常方便传递给第三方库的回调参数。

答案 3 :(得分:21)

从Facebook查看新的Flow库,"静态类型检查器,旨在查找JavaScript程序中的类型错误"

定义:

/* @flow */
function foo(x: string, y: number): string {
  return x.length * y;
}
foo('Hello', 42);

类型检查:

$> flow
hello.js:3:10,21: number
This type is incompatible with
  hello.js:2:37,42: string

这是how to run it

答案 4 :(得分:12)

不,相反,您需要根据自己的需要做这样的事情:

function myFunction(myDate, myString) {
  if(arguments.length > 1 && typeof(Date.parse(myDate)) == "number" && typeof(myString) == "string") {
    //Code here
  }
}

答案 5 :(得分:10)

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

  

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

以下实施以简单但非常强的方式说明了主要观点:



/*
 * 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
&#13;
&#13;
&#13;

答案 6 :(得分:9)

它没有内置于语言中,但您可以很容易地自己完成。 Vibhu的答案是我认为Javascript中典型的类型检查方式。如果你想要更通用的东西,尝试这样的事情:(只是一个让你入门的例子)

typedFunction = function(paramsList, f){
    //optionally, ensure that typedFunction is being called properly  -- here's a start:
    if (!(paramsList instanceof Array)) throw Error('invalid argument: paramsList must be an array');

    //the type-checked function
    return function(){
        for(var i=0,p,arg;p=paramsList[i],arg=arguments[i],i<paramsList.length; i++){
            if (typeof p === 'string'){
                if (typeof arg !== p) throw new Error('expected type ' + p + ', got ' + typeof arg);
            }
            else { //function
                if (!(arg instanceof p)) throw new Error('expected type ' + String(p).replace(/\s*\{.*/, '') + ', got ' + typeof arg);
            }
        }
        //type checking passed; call the function itself
        return f.apply(this, arguments);
    }
}

//usage:
var ds = typedFunction([Date, 'string'], function(d, s){
    console.log(d.toDateString(), s.substr(0));
});

ds('notadate', 'test');
//Error: expected type function Date(), got string
ds();
//Error: expected type function Date(), got undefined
ds(new Date(), 42);
//Error: expected type string, got number
ds(new Date(), 'success');
//Fri Jun 14 2013 success

答案 7 :(得分:4)

可以使用ArgueJS轻松完成:

function myFunction ()
{
  arguments = __({myDate: Date, myString: String});
  // do stuff
};

答案 8 :(得分:3)

说明

我不确定我的回答是否是对原始问题的直接回答,但我想很多人来到这里只是想找到一种方法来告诉他们的 IDE 理解类型,我'将分享我的发现。

如果您想让 VSCode 了解您的类型,请执行以下操作。请注意,js 运行时和 NodeJS 根本不关心这些类型。

解决方案

1- 创建一个以 .d.ts 结尾的文件:例如:index.d.ts。您可以在另一个文件夹中创建此文件。例如:types/index.d.ts
2- 假设我们想要一个名为 view 的函数。将这些行添加到 index.d.ts

/**
 * Use express res.render function to render view file inside layout file.
 *
 * @param {string} view The path of the view file, relative to view root dir.
 * @param {object} options The options to send to view file for ejs to use when rendering.
 * @returns {Express.Response.render} .
 */
view(view: string, options?: object): Express.Response.render;

3- 在您的项目根目录中创建一个 jsconfig.json 文件。 (似乎只要创建这个文件就足以让 VSCode 搜索您的类型)。

多一点

现在假设我们要将此类型添加到其他库类型。 (以我自己的情况为例)。我们可以使用一些 ts 关键字。只要 VSCode 理解 ts,我们就没有问题。
例如,如果您想将此 view 函数添加到 expressjs 的响应中,请按如下方式更改 index.d.ts 文件:

export declare global {
  namespace Express {
    interface Response {
      /**
       * Use express res.render function to render view file inside layout file.
       *
       * @param {string} view The path of the view file, relative to view root dir.
       * @param {object} options The options to send to view file for ejs to use when rendering.
       * @returns {Express.Response.render} .
       */
      view(view: string, options?: object): Express.Response.render;
    }
  }
}

结果

enter image description here

enter image description here

答案 9 :(得分:1)

使用 typeof instanceof

const assert = require('assert');

function myFunction(Date myDate, String myString)
{
    assert( typeof(myString) === 'string',  'Error message about incorrect arg type');
    assert( myDate instanceof Date,         'Error message about incorrect arg type');
}

答案 10 :(得分:1)

TypeScript是目前最好的解决方案之一

TypeScript通过向语言添加类型来扩展JavaScript。

https://www.typescriptlang.org/

答案 11 :(得分:0)

也许像这样的帮手功能。但是,如果您发现自己经常使用此类语法,则应该切换到Typescript。

function check(caller_args, ...types) {
    if(!types.every((type, index) => {
        if(typeof type === 'string')
            return typeof caller_args[index] === type
        return caller_args[index] instanceof type;
    })) throw Error("Illegal argument given");
}

function abc(name, id, bla) {
   check(arguments, "string", "number", MyClass)
   // code
}

答案 12 :(得分:0)

I've been thinking about this too. From a C background, you can simulate function return code types, as well as, parameter types, using

类似以下内容:

function top_function() {
    var rc;
    console.log("1st call");
    rc = Number(test_function("number", 1, "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
    console.log("2nd call");
    rc = Number(test_function("number", "a", "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
}
function test_function(parm_type_1, parm_val_1, parm_type_2, parm_val_2) {
    if (typeof parm_val_1 !== parm_type_1) console.log("Parm 1 not correct type");
    if (typeof parm_val_2 !== parm_type_2) console.log("Parm 2 not correct type");
    return parm_val_1;
}

The Number before the calling function returns a Number type

无论返回的实际值的类型如何,如 第二个调用,其中typeof rc =数字,但值为NaN

the console.log for the above is:

1st call
typeof rc: number   rc: 1
2nd call
Parm 1 not correct type
typeof rc: number   rc: NaN

答案 13 :(得分:-1)

我假设您允许 IDE 帮助您;那么下面的答案可能会对您有所帮助。

IDE: jetbrains/Golang 如果你的 IDE 不是这个也没关系。相信所有支持JSDoc的IDE,都能满足你的大部分需求。

它可以很好地显示JSDoc

演示

我的/pkg/encoding/base64.js

/**
 * Convert string to the base64 format.
 *
 * @param str {string} Input string
 * @returns {string} some message about return...
 * @example
 *  - btoa(toBinary("☸☹☺☻☼☾☿"))
 *  - Str2base64("☸☹☺☻☼☾☿")
 * @see https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa#unicode_strings
 */
export function Str2base64(str) {
  return btoa(toBinary(str))
}

test.js

import * as base64 from "../pkg/encoding/base64"
const filenameB64 = base64.Str2base64("test")

enter image description here

有用的 JSDoc 文档

其他链接