它似乎是一个本土的强类型设置:
/**
* A recursive descent analyzer which takes a value and a typehint, validating
* whether or not the value matches the typehint.
* The function will call it self as long as both the value and the typehint
* yields a nested component. This means that we will never recurse deeper
* than needed, and also that we automatically get support for
* > equals([], 'array<string>') // true
* > equals(['string'], 'array') // true
*/
function equals(value, node) {
var type = typeof value;
var subType;
var nextNode;
var nextValue;
//: Nullable types are delimited with a leading ?
//: ?string, ?boolean, etc.
var nullable = /^\?/.test(node);
if (nullable) {
node = node.substring(1);
}
//: snip ...
switch (type) {
// start by testing the most common types
case 'boolean':
case 'number':
case 'string':
case 'undefined':
break;
default:
//: snip ...
// let functions with signatures also match 'function'
type = value.__TCmeta && node !== 'function'
? value.__TCmeta.signature
: 'function';
} else if (type === 'object' || type === 'function') {
// HTMLObjectElements has a typeof function in FF
var constructor = value.constructor;
if (constructor && constructor.__TCmeta) {
// The value is a custom type
//: snip ...
while (constructor && constructor.__TCmeta) {
if (constructor.__TCmeta.type == node) {
type = node;
break;
}
constructor = constructor.__TCmeta.superClass;
}
//: snip ...
}
}
}
}
if (nullable && /undefined|null/.test(type)) {
return true;
}
if (type in typeInterfaces) {
var interfaces = typeInterfaces[type], i = interfaces.length;
while (i--) {
if (interfaces[i] === node) {
type = node;
break;
}
}
}
currentType.push(type);
return nextValue && nextNode
? node === type && equals(nextValue, nextNode)
: subType && nextNode
? node === type && subType === nextNode
: node === type;
}
/**
* Given a value and a typehint (can be a union type), this will return
* whether or not the passed in value matches the typehint.
*/
function matches(value, node) {
var nodes = node.split('|'), i = nodes.length;
while (i--) {
currentType = [];
if (equals(value, nodes[i])) {
return true;
}
}
return false;
}
他们使用该annotate
函数的原因是允许对自定义类型和函数签名进行类型提示。没有annotate
你只能做matches(someVar, "function")
。annotate
你可以做matches(someVar, "function(string, ?int)|function(string)")
并且只接受接受字符串和可为空的函数integer
或只接受字符串的函数。