Доброго времени суток!
Недавно я решил упростить себе жизнь и написать библиотеку для работы с типами данных. Так получилась types.js.
Библиотека самостоятельна и не требует никаких других.
Библиотека умеет регистрировать типы данных в достаточно удобной форме
types.test также может принимать первым аргументом массив с именами типов, и будет проверять значение на соответсвие хотя бы одному из типов.
Для этого нужно просто создать валидатор, передав в него массив с описанием типов
Либо в сокращённой нотации
И использовать, передавая массив или arguments.
Последняя, не менее важная возможность библиотеки — обёртка для упрощения создания перегруженных методов.
Всё, что нужно, создать метод, передав в волшебную функцию types.overload массив, где по чётным — сигнатуры, по нечётным — методы.
Если в конце ещё передать одинокую функцию, то она вызовется после выполнения функцию с нужной сигнатурой, и принимать должна её результат.
Chrome, Firefox, Opera, IE7+(в 6 не тестировалась)
Буду рад отзывам, критике, найденным багам.
Исходники на github тут
Скачать development версию (13kb) тут
Скачать production версию (5kb) тут
Недавно я решил упростить себе жизнь и написать библиотеку для работы с типами данных. Так получилась types.js.
Библиотека самостоятельна и не требует никаких других.
Что умеет
- Описывать типы
- Валидировать аргументы
- Перегружать методы
Регистрация типов
Библиотека умеет регистрировать типы данных в достаточно удобной форме
types.register("Array", {
// метод для тестирования значения
test: function(value) {
return value instanceof Array;
},
// Тип может быть контейнером для других значений, например массив. Но также это может быть
// что-то вроде сеттера-геттера (как observable из knockoutjs), поэтому мы не можем знать, как перебрать или достать эти
// самые значения. Этот метод должен быть, если мы хотим уметь тестировать значения внутри типа
valueTest: function(object, type) {
for(var i = 0, l = object.length; i < l; i++) {
if(!types.test(type, object[i])) {
return false;
}
}
return true;
},
// значение по-умолчанию
defaultValue: function() {
return [];
}
});
types.test("Array", []); // true
types.test("Array", {}); // false
types.get("Array").test([]); // true
types.get("Array").test({}); // false
// Проверить, все ли значения в массиве типа Number
types.get("Array").testValue([1, 2, 3, 4], "Number"); // true
types.get("Array").testValue(["1", "2", "3", "4"], "Number"); // false
// получить значение по-умолчанию
types.get("Array").getDefault(); // []
types.test также может принимать первым аргументом массив с именами типов, и будет проверять значение на соответсвие хотя бы одному из типов.
types.test(["Number", "Boolean", "String"], 1); // true
types.test(["Number", "Boolean", "String"], false); // true
types.test(["Number", "Boolean", "String"], "1"); // true
types.test(["Number", "Boolean", "String"], new Date()); // false
Валидация аргументов
Для этого нужно просто создать валидатор, передав в него массив с описанием типов
var myValidator = new types.Validator([
// first value should be a number
{
type: "Number"
},
// second value should be an Array of numbers
{
type: "Array",
of: "Number"
},
// third value should be a number or an Array of strings
{
type: ["Number", "Array"],
of: "String"
},
// fourth value should pass a custom test
{
type: function(value) {
return value == "uf-uf";
},
}
]);
Либо в сокращённой нотации
var myValidator = new types.Validator([
"Number",
// type:of, array of numbers
{"Array": "Number"},
// number or array of strings
["Number", {"Array": "String"}],
// custom test
function(value) {
return value == "uf-uf";
}
]);
И использовать, передавая массив или arguments.
// 0 - number, 1 - array, 2 - number, 3 - "uf-uf" - всё ок
myValidator.test([1, [2], 3, "uf-uf"]); // true
// массив содержит не только number
myValidator.test([1, [2, ""], 3]); // false
// третий агрумент может быть либо числом, либо массивом строк
myValidator.test([1, [2], [3], "uf-uf"]); // false
// тут всё хорошо
myValidator.test([1, [2], [""], "uf-uf"]); // true
Перегрузка
Последняя, не менее важная возможность библиотеки — обёртка для упрощения создания перегруженных методов.
Всё, что нужно, создать метод, передав в волшебную функцию types.overload массив, где по чётным — сигнатуры, по нечётным — методы.
var simple = types.overload([
// Если передать число и строку
["Number", "String"],
function(age, name) {
return 1;
},
// Если передать массив, boolean и строку
["Array", "Boolean", "String"],
function(list, isMad, name) {
return 2;
}
],
// в каком контексте будут вызываться методы
this);
simple(1, "Vasia"); // 1
simple([], true, "Vasia"); // 2
Если в конце ещё передать одинокую функцию, то она вызовется после выполнения функцию с нужной сигнатурой, и принимать должна её результат.
// overloading with 'final' metod
var withFinal = types.overload([
["Number", "String"],
function(age, name) {
return 1;
},
["Array", "Boolean", "String"],
function(list, isMad, name) {
return 2;
},
// final method
function(num) {
if(num === 1) {
return true;
} else {
return false;
}
}
],
// scope
this);
withFinal(1, "Vasia"); // true
withFinal([], true, "Vasia"); // false
Типы «из коробки»
- Any
- Array
- Function
- Number
- Numeric (не NaN и не Infinity, тольк тру числа)
- String
- Boolean
- Date
- Regexp
- Object
- Timestamp
- TimestampM (13-ти значный валидный таймстамп)
Поддержка браузерами
Chrome, Firefox, Opera, IE7+(в 6 не тестировалась)
Буду рад отзывам, критике, найденным багам.
Ресурсы
Исходники на github тут
Скачать development версию (13kb) тут
Скачать production версию (5kb) тут