Подтвердить что ты не робот

Установить тип для параметров функции?

Есть ли способ, чтобы функция javascript знала, что определенный параметр имеет определенный тип?

Возможность сделать что-то вроде этого будет идеальной:

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

Спасибо!

Обновление. Поскольку ответ является громким "нет", если я хочу, чтобы myDate рассматривался как дата (для того, чтобы называть функции даты на нем), я должен использовать это как дата внутри функции или установить новую переменную типа Date для нее?

4b9b3361

Ответ 1

Нет, JavaScript не является статически типизированным языком. Иногда вам может потребоваться вручную проверить типы параметров в вашем теле функции.

Ответ 2

Не в 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

Ответ 3

Хотя вы не можете сообщить языку JavaScript о типах, вы можете сообщить в IDE о них, так что вы получите гораздо более полезное автозаполнение.

Вот два способа сделать это:

  1. Используйте JSDoc, систему для документирования кода JavaScript. В частности, вам понадобится директива @param:
/**
 * @param {Date} myDate - The date
 * @param {string} myString - The string
 */
function myFunction(myDate, myString) {
  // ...
}
  1. Используйте подсказку типа, указав тип непосредственно перед параметром в /* comment */:

JavaScript type hinting in WebStorm

Это довольно распространенный метод, используемый, например, ReactJS. Очень удобно для параметров обратных вызовов, передаваемых сторонним библиотекам.

Ответ 4

Ознакомьтесь с новой библиотекой Flow от Facebook, "статической проверки типов, предназначенной для поиска ошибок типов в программах 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

И вот как его запустить.

Ответ 5

Нет, вместо этого вам нужно будет сделать что-то подобное в зависимости от ваших потребностей:

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

Ответ 6

Вы можете реализовать систему, которая обрабатывает проверки типов автоматически, используя оболочку в вашей функции.

При таком подходе вы можете создать полную 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

Ответ 7

Он не встроен в язык, но вы можете сделать это самостоятельно довольно легко. Ответ Vibhu - это то, что я хотел бы рассмотреть типичный способ проверки типов в Javascript. Если вы хотите что-то более обобщенное, попробуйте что-то вроде этого: (просто пример, чтобы вы начали)

typedFunction = function(paramsList, f){
    //optionally, ensure that typedFunction is being called properly  -- here 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

Ответ 8

Это легко сделать с помощью ArgueJS:

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

Ответ 9

Используйте 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

Может быть, такая вспомогательная функция. Но если вы регулярно используете такой синтаксис, вы, вероятно, должны перейти на 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
}

Ответ 11

Я тоже об этом думал. Из фона C можно моделировать типы кодов возврата функций, а также типы параметров, используя что-то вроде следующего:

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

Число перед вызывающей функцией возвращает тип Number независимо от типа возвращаемого фактического значения, как показано во втором вызове, где typeof rc = число, но значение равно NaN

console.log для вышеупомянутого:

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