Existe-t-il un moyen de faire savoir à une fonction javascript qu'un certain paramètre est d'un certain type?
Pouvoir faire quelque chose comme ça serait parfait:
function myFunction(Date myDate, String myString)
{
//do stuff
}
Je vous remercie!
Mise à jour: Étant donné que la réponse est un "non" retentissant, si je veux que myDate
soit traité comme une date (pour pouvoir appeler des fonctions de date dessus), je dois lancer la date dans la fonction ou une nouvelle variable de type Date?
Non, JavaScript n'est pas un langage statiquement typé. Parfois, vous devrez peut-être vérifier manuellement les types de paramètres dans votre corps de fonction.
Pas en JavaScript, mais en utilisant le mode avancé de Google Closure Compiler, vous pouvez le faire:
/**
* @param {Date} myDate The date
* @param {string} myString The string
*/
function myFunction(myDate, myString)
{
//do stuff
}
Voir http://code.google.com/closure/compiler/docs/js-for-compiler.html
Bien que vous ne puissiez pas informer JavaScript du langage à propos des types, vous pouvez en informer votre IDE), afin que vous obteniez l'auto-complétion beaucoup plus utile.
Voici deux façons de le faire:
@param
directive :/**
* @param {Date} myDate - The date
* @param {string} myString - The string
*/
function myFunction(myDate, myString) {
// ...
}
/* comment */
:C'est une technique assez répandue, utilisée par ReactJS par exemple. Très pratique pour les paramètres de rappel transmis aux bibliothèques tierces.
Découvrez la nouvelle bibliothèque Flow de Facebook, "un vérificateur de type statique, conçu pour rechercher les erreurs de type dans les programmes JavaScript"
Définition:
/* @flow */
function foo(x: string, y: number): string {
return x.length * y;
}
foo('Hello', 42);
Vérification de type:
$> flow
hello.js:3:10,21: number
This type is incompatible with
hello.js:2:37,42: string
Et voici comment l'exécuter .
Non, vous devriez plutôt faire quelque chose comme ceci en fonction de vos besoins:
function myFunction(myDate, myString) {
if(arguments.length > 1 && typeof(Date.parse(myDate)) == "number" && typeof(myString) == "string") {
//Code here
}
}
Vous pouvez implémenter un système qui gère les vérifications de type automatiquement , en utilisant un wrapper dans votre fonction.
Avec cette approche, vous pouvez construire un
declarative type check system
qui gérera pour vous les vérifications de type. Si vous souhaitez approfondir ce concept, consultez le Bibliothèque Functyped
L’implémentation suivante illustre l’idée principale, de manière simpliste mais fonctionnelle :
/*
* 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
Cela ne fait pas partie de la langue, mais vous pouvez le faire vous-même assez facilement. La réponse de Vibhu est ce que je considérerais comme la méthode typique de vérification de type en Javascript. Si vous voulez quelque chose de plus général, essayez quelque chose comme ceci: (juste un exemple pour vous aider à démarrer)
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
Cela peut facilement être fait avec ArgueJS :
function myFunction ()
{
arguments = __({myDate: Date, myString: String});
// do stuff
};
Utilisez typeof
ou 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');
}
J'y ai pensé aussi. A partir d'un arrière-plan C, vous pouvez simuler des types de code de retour de fonction, ainsi que des types de paramètre, en utilisant l'une des méthodes suivantes:
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;
}
Le nombre avant la fonction appelante renvoie un type de numéro, quel que soit le type de la valeur réelle renvoyée, comme indiqué dans le deuxième appel, où typeof rc = nombre mais la valeur est NaN.
le fichier console.log pour ce qui précède est:
1st call
typeof rc: number rc: 1
2nd call
Parm 1 not correct type
typeof rc: number rc: NaN
Peut-être qu'un assistant fonctionne comme ça. Mais si vous voyez vous-même utiliser régulièrement cette syntaxe, vous devriez probablement passer à 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
}