Есть ли способ, чтобы функция javascript знала, что определенный параметр имеет определенный тип?
Возможность сделать что-то вроде этого будет идеальной:
function myFunction(Date myDate, String myString)
{
//do stuff
}
Спасибо!
Обновление. Поскольку ответ является громким "нет", если я хочу, чтобы myDate
рассматривался как дата (для того, чтобы называть функции даты на нем), я должен использовать это как дата внутри функции или установить новую переменную типа Date для нее?
Ответ 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 о них, так что вы получите гораздо более полезное автозаполнение.
Вот два способа сделать это:
- Используйте JSDoc, систему для документирования кода JavaScript. В частности, вам понадобится директива
@param
:
/**
* @param {Date} myDate - The date
* @param {string} myString - The string
*/
function myFunction(myDate, myString) {
// ...
}
- Используйте подсказку типа, указав тип непосредственно перед параметром в
/* 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