Javascript 设置函数参数的类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8407622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:53:42  来源:igfitidea点击:

Set type for function parameters?

javascriptfunction

提问by dmr

Is there a way to let a javascript function know that a certain parameter is of a certain type?

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

Being able to do something like this would be perfect:

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

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

Thank you!

谢谢!

Update: Being that the answer is a resounding "no," if I want myDateto be treated as a date (in order to call date functions on it), I have to cast it as a date inside the function or set a new variable of type Date to it?

更新:由于答案是响亮的“不”,如果我想myDate被视为日期(以便对其调用日期函数),我必须将其转换为函数内的日期或设置一个新变量输入日期吗?

回答by pronvit

No, JavaScript is not a statically typed language. Sometimes you may need to manually check types of parameters in your function body.

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

回答by eolsson

Not in javascript it self but using Google Closure Compiler's advanced mode you can do that:

不是在 javascript 中,而是使用 Google Closure Compiler 的高级模式,您可以这样做:

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

See http://code.google.com/closure/compiler/docs/js-for-compiler.html

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

回答by Dan Dascalescu

While you can't inform JavaScript the languageabout types, you can inform your IDE about them, so you get much more useful autocompletion.

虽然您无法有关类型的语言告知 JavaScript ,但您可以将它们告知您的 IDE,因此您可以获得更有用的自动完成功能。

Here are two ways to do that:

这里有两种方法可以做到这一点:

  1. Use JSDoc, a system for documenting JavaScript code in comments. In particular, you'll need the @paramdirective:

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

    You can also use JSDoc to define custom typesand specify those in @paramdirectives, but note that JSDoc won't do any type checking; it's only a documentation tool. To check types defined in JSDoc, look into TypeScript, which can parse JSDoc tags.

  2. Use type hinting by specifying the type right before the parameter in a
    /* comment */:

    JavaScript type hinting in WebStorm

    This is a pretty widespread technique, used by ReactJSfor instance. Very handy for parameters of callbacks passed to 3rd party libraries.

  1. 使用JSDoc,一种在注释中记录 JavaScript 代码的系统。特别是,您将需要@param指令

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

    您也可以使用 JSDoc 来定义自定义类型并在@param指令中指定这些类型,但请注意 JSDoc 不会进行任何类型检查;它只是一个文档工具。要检查 JSDoc 中定义的类型,请查看TypeScript,它可以解析 JSDoc 标签

  2. 通过在 a 中的参数之前指定类型来使用类型提示
    /* comment */

    WebStorm 中的 JavaScript 类型提示

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

TypeScript

打字稿

For actual type checking, the closest solution is to use TypeScript, a (mostly) superset of JavaScript. Here's TypeScript in 5 minutes.

对于实际的类型检查,最接近的解决方案是使用 TypeScript,一个(主要是)JavaScript 的超集。这是5 分钟后TypeScript

回答by Renaud

Check out the new Flowlibrary from Facebook, "a static type checker, designed to find type errors in JavaScript programs"

查看来自 Facebook的新Flow库,“一个静态类型检查器,旨在查找 JavaScript 程序中的类型错误”

Definition:

定义:

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

Type checking:

类型检查:

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

And here is how to run it.

这是如何运行它

回答by VNO

No, instead you would need to do something like this depending on your needs:

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

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

回答by undefined

Edit: Seven years later, this answer still gets occasional upvotes. It's fine if you are looking for runtime checking, but I would now recommend compile-time type checking using Typescript, or possibly Flow. See https://stackoverflow.com/a/31420719/610585above for more.

编辑:七年后,这个答案仍然偶尔会得到赞成。如果您正在寻找运行时检查,那很好,但我现在建议使用 Typescript 或 Flow 进行编译时类型检查。有关更多信息,请参阅上面的https://stackoverflow.com/a/31420719/610585

Original answer:

原答案:

It's not built into the language, but you can do it yourself quite easily. Vibhu's answer is what I would consider the typical way of type checking in Javascript. If you want something more generalized, try something like this: (just an example to get you started)

它没有内置在语言中,但您可以很容易地自己完成。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

回答by colxi

You can implement a system that handles the type checks automatically, using a wrapper in your function.

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

With this approach, you can build a complete declarative type check systemthat will manage for you the type checks . If you are interested in taking a more in depth look at this concept, check the Functyped library

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

The following implementation illustrates the main idea, in a simplistic, but operative way:

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

/*
 * 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

回答by zVictor

It can easilly be done with ArgueJS:

它可以easilly可以用做ArgueJS

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

回答by fider

Use typeofor instanceof:

使用typeofinstanceof

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');
}

回答by phil294

Maybe a helper function like this. But if you see yourself using such syntax regularly, you should probably switch to Typescript.

也许是这样的辅助功能。但是如果你发现自己经常使用这样的语法,你可能应该切换到 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
}