UNPKG

30.6 kBJavaScriptView Raw
1import TypeInferrer from './TypeInferrer';
2import primitiveTypes from './primitiveTypes';
3import invariant from './invariant';
4
5import Validation from './Validation';
6
7import makeReactPropTypes from './makeReactPropTypes';
8
9import _makeJSONError from './errorReporting/makeJSONError';
10import _makeTypeError from './errorReporting/makeTypeError';
11import makeWarningMessage from './errorReporting/makeWarningMessage';
12
13import makeUnion from './makeUnion';
14import { makePropertyDescriptor } from './classDecorators';
15
16import { flowIntoTypeParameter } from './types/TypeParameter';
17
18import annotateValue from './annotateValue';
19
20import { Type, TypeParameter, TypeBox, TypeReference, ParameterizedTypeAlias, TypeAlias, TypeConstructor, GenericType, NullLiteralType, NumberType, NumericLiteralType, BooleanType, BooleanLiteralType, SymbolType, SymbolLiteralType, StringType, StringLiteralType, ArrayType, ObjectType, ObjectTypeCallProperty, ObjectTypeIndexer, ObjectTypeProperty, FlowIntoType, FunctionType, ParameterizedFunctionType, FunctionTypeParam, FunctionTypeRestParam, FunctionTypeReturn, GeneratorType, ExistentialType, AnyType, MixedType, EmptyType, NullableType, TupleType, UnionType, IntersectionType, VoidType, RefinementType } from './types';
21
22import { Declaration, TypeDeclaration, VarDeclaration, ModuleDeclaration, ModuleExportsDeclaration, ClassDeclaration, ExtendsDeclaration } from './declarations';
23
24import { ParentSymbol, NameRegistrySymbol, ModuleRegistrySymbol, CurrentModuleSymbol, TypeConstructorRegistrySymbol, TypeParametersSymbol, InferrerSymbol, TypePredicateRegistrySymbol, TypeSymbol } from './symbols';
25
26/**
27 * Keeps track of invalid references in order to prevent
28 * multiple warnings.
29 */
30var warnedInvalidReferences = new WeakSet();
31
32var TypeContext = function () {
33 function TypeContext() {
34 babelHelpers.classCallCheck(this, TypeContext);
35 this.mode = 'assert';
36 this[NameRegistrySymbol] = {};
37 this[TypePredicateRegistrySymbol] = {};
38 this[TypeConstructorRegistrySymbol] = new Map();
39 this[InferrerSymbol] = new TypeInferrer(this);
40 this[ModuleRegistrySymbol] = {};
41 }
42
43 /**
44 * Calls to `t.check(...)` will call either
45 * `t.assert(...)` or `t.warn(...)` depending on this setting.
46 */
47
48
49 // Issue 252
50
51
52 // Issue 252
53
54
55 // Issue 252
56
57
58 // Issue 252
59
60
61 // Issue 252
62
63
64 // Issue 252
65
66
67 babelHelpers.createClass(TypeContext, [{
68 key: 'makeJSONError',
69
70
71 // Issue 252
72 value: function makeJSONError(validation) {
73 return _makeJSONError(validation);
74 }
75 }, {
76 key: 'makeTypeError',
77 value: function makeTypeError(validation) {
78 return _makeTypeError(validation);
79 }
80 }, {
81 key: 'createContext',
82 value: function createContext() {
83 var context = new TypeContext();
84 // Issue 252
85 context[ParentSymbol] = this;
86 return context;
87 }
88 }, {
89 key: 'typeOf',
90 value: function typeOf(input) {
91
92 var annotation = this.getAnnotation(input);
93 if (annotation) {
94 return annotation;
95 }
96 // Issue 252
97 var inferrer = this[InferrerSymbol];
98 inferrer;
99
100 return inferrer.infer(input);
101 }
102 }, {
103 key: 'get',
104 value: function get(name) {
105 // Issue 252
106 var item = this[NameRegistrySymbol][name];
107 if (item != null) {
108 if (typeof item === 'function') {
109 return new item(this);
110 } else {
111 return item;
112 }
113 }
114 // Issue 252
115 var parent = this[ParentSymbol];
116 if (parent) {
117 return parent.get(name);
118 }
119 }
120
121 /**
122 * Get the predicate for a given type name.
123 * e.g. `t.getPredicate('Array')`.
124 */
125
126 }, {
127 key: 'getPredicate',
128 value: function getPredicate(name) {
129 var item = this[TypePredicateRegistrySymbol][name];
130 if (item) {
131 return item;
132 }
133 var parent = this[ParentSymbol];
134 if (parent) {
135 return parent.getPredicate(name);
136 }
137 }
138
139 /**
140 * Set the predicate for a given type name.
141 * This can be used to customise the behaviour of things like Array
142 * detection or allowing Thenables in place of the global Promise.
143 */
144
145 }, {
146 key: 'setPredicate',
147 value: function setPredicate(name, predicate) {
148 this[TypePredicateRegistrySymbol][name] = predicate;
149 }
150
151 /**
152 * Check the given value against the named predicate.
153 * Returns false if no such predicate exists.
154 * e.g. `t.checkPredicate('Array', [1, 2, 3])`
155 */
156
157 }, {
158 key: 'checkPredicate',
159 value: function checkPredicate(name, input) {
160 var predicate = this.getPredicate(name);
161 if (predicate) {
162 return predicate(input);
163 } else {
164 return false;
165 }
166 }
167
168 /**
169 * Returns a decorator for a function or object with the given type.
170 */
171
172 }, {
173 key: 'decorate',
174 value: function decorate(type) {
175 var _this = this;
176
177 return function (input, propertyName, descriptor) {
178 if (descriptor && typeof propertyName === 'string') {
179 return makePropertyDescriptor(type, input, propertyName, descriptor);
180 } else {
181 invariant(typeof type !== 'function', 'Cannot decorate an object or function as a method.');
182 return _this.annotate(input, type);
183 }
184 };
185 }
186
187 /**
188 * Annotates an object or function with the given type.
189 * If a type is specified as the sole argument, returns a
190 * function which can decorate classes or functions with the given type.
191 */
192
193 }, {
194 key: 'annotate',
195 value: function annotate(input, type) {
196 if (type === undefined) {
197 return annotateValue(input);
198 } else {
199 return annotateValue(input, type);
200 }
201 }
202 }, {
203 key: 'getAnnotation',
204 value: function getAnnotation(input) {
205 if (input !== null && typeof input === 'object' || typeof input === 'function') {
206 // Issue 252
207 return input[TypeSymbol];
208 }
209 }
210 }, {
211 key: 'hasAnnotation',
212 value: function hasAnnotation(input) {
213 if (input == null) {
214 return false;
215 } else {
216 return input[TypeSymbol] ? true : false;
217 }
218 }
219 }, {
220 key: 'setAnnotation',
221 value: function setAnnotation(input, type) {
222 input[TypeSymbol] = type;
223 return input;
224 }
225 }, {
226 key: 'type',
227 value: function type(name, _type) {
228 if (typeof _type === 'function') {
229 var target = new ParameterizedTypeAlias(this);
230 target.name = name;
231 target.typeCreator = _type;
232 return target;
233 } else {
234 var _target = new TypeAlias(this);
235 _target.name = name;
236 _target.type = _type;
237 return _target;
238 }
239 }
240 }, {
241 key: 'declare',
242 value: function declare(name, type) {
243
244 if (name instanceof Declaration) {
245 type = name;
246 name = type.name;
247 } else if (name instanceof TypeAlias) {
248 type = name;
249 name = type.name;
250 }
251 if (typeof type === 'function') {
252 type = this.type(name, type);
253 }
254 if (type instanceof ModuleDeclaration) {
255 var moduleRegistry = this[ModuleRegistrySymbol];
256 if (moduleRegistry[name]) {
257 throw new Error(`Cannot redeclare module: ${ name }`);
258 }
259 moduleRegistry[name] = type;
260 return type;
261 } else {
262 invariant(type, 'Type must be supplied to declaration');
263 var nameRegistry = this[NameRegistrySymbol];
264
265 if (nameRegistry[name]) {
266 throw new Error(`Cannot redeclare type: ${ name }`);
267 }
268 if (type instanceof Declaration) {
269 nameRegistry[name] = type;
270 return type;
271 } else if (type instanceof TypeAlias || type instanceof ParameterizedTypeAlias) {
272 var target = new TypeDeclaration(this);
273 target.name = name;
274 target.typeAlias = type;
275 nameRegistry[name] = target;
276 return target;
277 } else {
278 var _target2 = this.var(name, type);
279 nameRegistry[name] = _target2;
280 return _target2;
281 }
282 }
283 }
284 }, {
285 key: 'declarations',
286 value: function* declarations() {
287 var nameRegistry = this[NameRegistrySymbol];
288 for (var key in nameRegistry) {
289 // eslint-disable-line guard-for-in
290 yield [key, nameRegistry[key]];
291 }
292 }
293 }, {
294 key: 'modules',
295 value: function* modules() {
296 var moduleRegistry = this[ModuleRegistrySymbol];
297 for (var key in moduleRegistry) {
298 // eslint-disable-line guard-for-in
299 yield moduleRegistry[key];
300 }
301 }
302 }, {
303 key: 'import',
304 value: function _import(moduleName) {
305 var moduleRegistry = this[ModuleRegistrySymbol];
306 if (moduleRegistry[moduleName]) {
307 return moduleRegistry[moduleName];
308 }
309
310 var _moduleName$split = moduleName.split('/'),
311 _moduleName$split2 = babelHelpers.slicedToArray(_moduleName$split, 1),
312 head = _moduleName$split2[0];
313
314 var module = moduleRegistry[head];
315 if (module) {
316 return module.import(moduleName);
317 }
318 var parent = this[ParentSymbol];
319 if (parent) {
320 return parent.import(moduleName);
321 }
322 }
323 }, {
324 key: 'declareTypeConstructor',
325 value: function declareTypeConstructor(_ref) {
326 var name = _ref.name,
327 impl = _ref.impl,
328 typeName = _ref.typeName,
329 collectErrors = _ref.collectErrors,
330 accepts = _ref.accepts,
331 inferTypeParameters = _ref.inferTypeParameters;
332
333 var nameRegistry = this[NameRegistrySymbol];
334
335 if (nameRegistry[name]) {
336 throw new Error(`Cannot redeclare type: ${ name }`);
337 }
338
339 var target = new TypeConstructor(this);
340 target.name = name;
341 target.typeName = typeName;
342 target.impl = impl;
343 target.collectErrors = collectErrors;
344 target.accepts = accepts;
345 target.inferTypeParameters = inferTypeParameters;
346
347 nameRegistry[name] = target;
348
349 if (typeof impl === 'function') {
350 // Issue 252
351 var handlerRegistry = this[TypeConstructorRegistrySymbol];
352 handlerRegistry;
353
354 if (handlerRegistry.has(impl)) {
355 throw new Error(`A type handler already exists for the given implementation.`);
356 }
357 handlerRegistry.set(impl, target);
358 }
359 return target;
360 }
361 }, {
362 key: 'getTypeConstructor',
363 value: function getTypeConstructor(impl) {
364 // Issue 252
365 var handlerRegistry = this[TypeConstructorRegistrySymbol];
366 handlerRegistry;
367
368 return handlerRegistry.get(impl);
369 }
370 }, {
371 key: 'null',
372 value: function _null() {
373 return primitiveTypes.null;
374 }
375 }, {
376 key: 'nullable',
377 value: function nullable(type) {
378 var target = new NullableType(this);
379 target.type = type;
380 return target;
381 }
382 }, {
383 key: 'existential',
384 value: function existential() {
385 return primitiveTypes.existential;
386 }
387 }, {
388 key: 'empty',
389 value: function empty() {
390 return primitiveTypes.empty;
391 }
392 }, {
393 key: 'any',
394 value: function any() {
395 return primitiveTypes.any;
396 }
397 }, {
398 key: 'mixed',
399 value: function mixed() {
400 return primitiveTypes.mixed;
401 }
402 }, {
403 key: 'void',
404 value: function _void() {
405 return primitiveTypes.void;
406 }
407 }, {
408 key: 'number',
409 value: function number(input) {
410 if (input !== undefined) {
411 var target = new NumericLiteralType(this);
412 target.value = input;
413 return target;
414 } else {
415 return primitiveTypes.number;
416 }
417 }
418 }, {
419 key: 'boolean',
420 value: function boolean(input) {
421 if (input !== undefined) {
422 var target = new BooleanLiteralType(this);
423 target.value = input;
424 return target;
425 } else {
426 return primitiveTypes.boolean;
427 }
428 }
429 }, {
430 key: 'string',
431 value: function string(input) {
432 if (input !== undefined) {
433 var target = new StringLiteralType(this);
434 target.value = input;
435 return target;
436 } else {
437 return primitiveTypes.string;
438 }
439 }
440 }, {
441 key: 'symbol',
442 value: function symbol(input) {
443 if (input !== undefined) {
444 var target = new SymbolLiteralType(this);
445 target.value = input;
446 return target;
447 } else {
448 return primitiveTypes.symbol;
449 }
450 }
451 }, {
452 key: 'typeParameter',
453 value: function typeParameter(id, bound) {
454 var target = new TypeParameter(this);
455 target.id = id;
456 target.bound = bound;
457 return target;
458 }
459 }, {
460 key: 'flowInto',
461 value: function flowInto(typeParameter) {
462 return flowIntoTypeParameter(typeParameter);
463 }
464
465 /**
466 * Bind the type parameters for the parent class of the given instance.
467 */
468
469 }, {
470 key: 'bindTypeParameters',
471 value: function bindTypeParameters(subject) {
472
473 var instancePrototype = Object.getPrototypeOf(subject);
474 // Issue
475 var parentPrototype = instancePrototype && Object.getPrototypeOf(instancePrototype);
476 // Issue
477 var parentClass = parentPrototype && parentPrototype.constructor;
478
479 if (!parentClass) {
480 this.emitWarningMessage('Could not bind type parameters for non-existent parent class.');
481 return subject;
482 }
483 // Issue 252
484 var typeParametersPointer = parentClass[TypeParametersSymbol];
485
486 if (typeParametersPointer) {
487 var typeParameters = subject[typeParametersPointer];
488 var keys = Object.keys(typeParameters);
489
490 for (var _len = arguments.length, typeInstances = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
491 typeInstances[_key - 1] = arguments[_key];
492 }
493
494 var length = Math.min(keys.length, typeInstances.length);
495 for (var i = 0; i < length; i++) {
496 var typeParam = typeParameters[keys[i]];
497 typeParam.bound = typeInstances[i];
498 }
499 }
500 return subject;
501 }
502 }, {
503 key: 'module',
504 value: function module(name, body) {
505 var target = new ModuleDeclaration(this);
506 target.name = name;
507 var innerContext = this.createContext();
508 // Issue 252
509 innerContext[ParentSymbol] = this;
510 // Issue 252
511 innerContext[CurrentModuleSymbol] = target;
512
513 target.innerContext = innerContext;
514 body(innerContext);
515 return target;
516 }
517 }, {
518 key: 'moduleExports',
519 value: function moduleExports(type) {
520 var currentModule = this[CurrentModuleSymbol];
521 if (!currentModule) {
522 throw new Error('Cannot declare module.exports outside of a module.');
523 }
524 var target = new ModuleExportsDeclaration(this);
525 target.type = type;
526 currentModule.moduleExports = target;
527 return target;
528 }
529 }, {
530 key: 'var',
531 value: function _var(name, type) {
532 var target = new VarDeclaration(this);
533 target.name = name;
534 target.type = type;
535 return target;
536 }
537 }, {
538 key: 'class',
539 value: function _class(name, head) {
540 var target = new ClassDeclaration(this);
541 if (typeof head === 'function') {
542 return target;
543 }
544 target.name = name;
545
546 for (var _len2 = arguments.length, tail = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
547 tail[_key2 - 2] = arguments[_key2];
548 }
549
550 tail.unshift(head);
551 var length = tail.length;
552
553 var properties = [];
554 var body = void 0;
555
556 for (var i = 0; i < length; i++) {
557 var item = tail[i];
558 if (item instanceof ObjectTypeProperty) {
559 properties.push(item);
560 } else if (item instanceof ObjectType) {
561 invariant(!body, 'Class body must only be declared once.');
562 body = item;
563 } else if (item instanceof ExtendsDeclaration) {
564 invariant(!target.superClass, 'Classes can only have one super class.');
565 target.superClass = item;
566 } else if (item != null && typeof item === 'object' && !(item instanceof Type)) {
567 for (var propertyName in item) {
568 // eslint-disable-line
569 properties.push(this.property(propertyName, item[propertyName]));
570 }
571 } else {
572 throw new Error('ClassDeclaration cannot contain the given type directly.');
573 }
574 }
575 if (!body) {
576 body = new ObjectType(this);
577 }
578 if (properties.length) {
579 var _body$properties;
580
581 (_body$properties = body.properties).push.apply(_body$properties, properties);
582 }
583 target.body = body;
584 return target;
585 }
586 }, {
587 key: 'extends',
588 value: function _extends(subject) {
589 var target = new ExtendsDeclaration(this);
590
591 for (var _len3 = arguments.length, typeInstances = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
592 typeInstances[_key3 - 1] = arguments[_key3];
593 }
594
595 target.type = this.ref.apply(this, [subject].concat(babelHelpers.toConsumableArray(typeInstances)));
596 return target;
597 }
598 }, {
599 key: 'fn',
600 value: function fn(head) {
601 for (var _len4 = arguments.length, tail = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
602 tail[_key4 - 1] = arguments[_key4];
603 }
604
605 return this.function.apply(this, [head].concat(tail));
606 }
607 }, {
608 key: 'function',
609 value: function _function(head) {
610 if (typeof head === 'function') {
611 var _target3 = new ParameterizedFunctionType(this);
612 _target3.bodyCreator = head;
613 return _target3;
614 }
615 var target = new FunctionType(this);
616
617 for (var _len5 = arguments.length, tail = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
618 tail[_key5 - 1] = arguments[_key5];
619 }
620
621 tail.unshift(head);
622 var length = tail.length;
623
624 for (var i = 0; i < length; i++) {
625 var item = tail[i];
626 if (item instanceof FunctionTypeParam) {
627 target.params.push(item);
628 } else if (item instanceof FunctionTypeRestParam) {
629 target.rest = item;
630 } else if (item instanceof FunctionTypeReturn) {
631 target.returnType = item;
632 } else {
633 throw new Error('FunctionType cannot contain the given type directly.');
634 }
635 }
636 if (!target.returnType) {
637 target.returnType = this.any();
638 }
639 return target;
640 }
641 }, {
642 key: 'param',
643 value: function param(name, type) {
644 var optional = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
645
646 var target = new FunctionTypeParam(this);
647 target.name = name;
648 target.type = type;
649 target.optional = optional;
650 return target;
651 }
652 }, {
653 key: 'rest',
654 value: function rest(name, type) {
655 var target = new FunctionTypeRestParam(this);
656 target.name = name;
657 target.type = type;
658 return target;
659 }
660 }, {
661 key: 'return',
662 value: function _return(type) {
663 var target = new FunctionTypeReturn(this);
664 target.type = type;
665 return target;
666 }
667 }, {
668 key: 'generator',
669 value: function generator(yieldType, returnType, nextType) {
670 var target = new GeneratorType(this);
671 target.yieldType = yieldType;
672 target.returnType = returnType || this.any();
673 target.nextType = nextType || this.any();
674 return target;
675 }
676 }, {
677 key: 'object',
678 value: function object(head) {
679 var target = new ObjectType(this);
680 if (head != null && typeof head === 'object' && !(head instanceof Type)) {
681 for (var propertyName in head) {
682 // eslint-disable-line
683 target.properties.push(this.property(propertyName, head[propertyName]));
684 }
685 } else {
686 var body = void 0;
687
688 for (var _len6 = arguments.length, tail = Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
689 tail[_key6 - 1] = arguments[_key6];
690 }
691
692 if (head) {
693 body = [head].concat(babelHelpers.toConsumableArray(tail));
694 } else {
695 body = tail;
696 }
697 var _body = body,
698 length = _body.length;
699
700 for (var i = 0; i < length; i++) {
701 var item = body[i];
702 if (item instanceof ObjectTypeProperty) {
703 target.properties.push(item);
704 } else if (item instanceof ObjectTypeIndexer) {
705 target.indexers.push(item);
706 } else if (item instanceof ObjectTypeCallProperty) {
707 target.callProperties.push(item);
708 } else {
709 throw new Error('ObjectType cannot contain the given type directly.');
710 }
711 }
712 }
713 return target;
714 }
715 }, {
716 key: 'exactObject',
717 value: function exactObject(head) {
718 for (var _len7 = arguments.length, tail = Array(_len7 > 1 ? _len7 - 1 : 0), _key7 = 1; _key7 < _len7; _key7++) {
719 tail[_key7 - 1] = arguments[_key7];
720 }
721
722 var object = this.object.apply(this, [head].concat(babelHelpers.toConsumableArray(tail)));
723 object.exact = true;
724 return object;
725 }
726 }, {
727 key: 'callProperty',
728 value: function callProperty(value) {
729 var target = new ObjectTypeCallProperty(this);
730 target.value = value;
731 return target;
732 }
733 }, {
734 key: 'property',
735 value: function property(key, value) {
736 var optional = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
737
738 var target = new ObjectTypeProperty(this);
739 target.key = key;
740 if (value instanceof Type) {
741 target.value = value;
742 } else {
743 target.value = this.object(value);
744 }
745 target.optional = optional;
746 return target;
747 }
748 }, {
749 key: 'indexer',
750 value: function indexer(id, key, value) {
751 var target = new ObjectTypeIndexer(this);
752 target.id = id;
753 target.key = key;
754 target.value = value;
755 return target;
756 }
757 }, {
758 key: 'method',
759 value: function method(name, head) {
760 var target = new ObjectTypeProperty(this);
761 target.key = name;
762
763 for (var _len8 = arguments.length, tail = Array(_len8 > 2 ? _len8 - 2 : 0), _key8 = 2; _key8 < _len8; _key8++) {
764 tail[_key8 - 2] = arguments[_key8];
765 }
766
767 target.value = this.function.apply(this, [head].concat(tail));
768 return target;
769 }
770 }, {
771 key: 'staticProperty',
772 value: function staticProperty(key, value) {
773 var optional = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
774
775 var prop = this.property(key, value, optional);
776 prop.static = true;
777 return prop;
778 }
779 }, {
780 key: 'staticMethod',
781 value: function staticMethod(name, head) {
782 for (var _len9 = arguments.length, tail = Array(_len9 > 2 ? _len9 - 2 : 0), _key9 = 2; _key9 < _len9; _key9++) {
783 tail[_key9 - 2] = arguments[_key9];
784 }
785
786 var prop = this.method.apply(this, [name, head].concat(tail));
787 prop.static = true;
788 return prop;
789 }
790 }, {
791 key: 'tuple',
792 value: function tuple() {
793 var target = new TupleType(this);
794
795 for (var _len10 = arguments.length, types = Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
796 types[_key10] = arguments[_key10];
797 }
798
799 target.types = types;
800 return target;
801 }
802 }, {
803 key: 'array',
804 value: function array(elementType) {
805 var target = new ArrayType(this);
806 target.elementType = elementType || this.any();
807 return target;
808 }
809 }, {
810 key: 'union',
811 value: function union() {
812 for (var _len11 = arguments.length, types = Array(_len11), _key11 = 0; _key11 < _len11; _key11++) {
813 types[_key11] = arguments[_key11];
814 }
815
816 return makeUnion(this, types);
817 }
818 }, {
819 key: 'intersect',
820 value: function intersect() {
821 var target = new IntersectionType(this);
822
823 for (var _len12 = arguments.length, types = Array(_len12), _key12 = 0; _key12 < _len12; _key12++) {
824 types[_key12] = arguments[_key12];
825 }
826
827 target.types = types;
828 return target;
829 }
830 }, {
831 key: 'intersection',
832 value: function intersection() {
833 return this.intersect.apply(this, arguments);
834 }
835 }, {
836 key: 'box',
837 value: function box(reveal) {
838 var box = new TypeBox(this);
839 box.reveal = reveal;
840 return box;
841 }
842 }, {
843 key: 'ref',
844 value: function ref(subject) {
845 var target = void 0;
846 if (typeof subject === 'string') {
847 // try and eagerly resolve the reference
848 target = this.get(subject);
849 if (!target) {
850 // defer dereferencing for now
851 target = new TypeReference(this);
852 target.name = subject;
853 }
854 } else if (typeof subject === 'function') {
855 // Issue 252
856 var handlerRegistry = this[TypeConstructorRegistrySymbol];
857 handlerRegistry;
858
859 // see if we have a dedicated TypeConstructor for this.
860 target = handlerRegistry.get(subject);
861
862 if (!target) {
863 // just use a generic type handler.
864 target = new GenericType(this);
865 target.impl = subject;
866 target.name = subject.name;
867 }
868 } else if (subject instanceof Type) {
869 target = subject;
870 } else {
871 if (!warnedInvalidReferences.has(subject)) {
872 this.emitWarningMessage('Could not reference the given type, try t.typeOf(value) instead.');
873 warnedInvalidReferences.add(subject);
874 }
875 return this.any();
876 }
877
878 for (var _len13 = arguments.length, typeInstances = Array(_len13 > 1 ? _len13 - 1 : 0), _key13 = 1; _key13 < _len13; _key13++) {
879 typeInstances[_key13 - 1] = arguments[_key13];
880 }
881
882 if (typeInstances.length) {
883 var _target4;
884
885 invariant(typeof target.apply === 'function', `Cannot apply non-applicable type: ${ target.typeName }.`);
886 return (_target4 = target).apply.apply(_target4, babelHelpers.toConsumableArray(typeInstances));
887 } else {
888 return target;
889 }
890 }
891 }, {
892 key: 'validate',
893 value: function validate(type, input) {
894 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
895 var path = arguments[3];
896
897 var validation = new Validation(this, input);
898 if (path) {
899 var _validation$path;
900
901 (_validation$path = validation.path).push.apply(_validation$path, babelHelpers.toConsumableArray(path));
902 } else if (typeof type.name === 'string') {
903 validation.path.push(type.name);
904 }
905 validation.prefix = prefix;
906 type.collectErrors(validation, [], input);
907 return validation;
908 }
909 }, {
910 key: 'check',
911 value: function check(type, input) {
912 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
913 var path = arguments[3];
914
915 if (this.mode === 'assert') {
916 return this.assert(type, input, prefix, path);
917 } else {
918 return this.warn(type, input, prefix, path);
919 }
920 }
921 }, {
922 key: 'assert',
923 value: function assert(type, input) {
924 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
925 var path = arguments[3];
926
927 var validation = this.validate(type, input, prefix, path);
928 var error = this.makeTypeError(validation);
929 if (error) {
930 throw error;
931 }
932 return input;
933 }
934 }, {
935 key: 'warn',
936 value: function warn(type, input) {
937 var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
938 var path = arguments[3];
939
940 var validation = this.validate(type, input, prefix, path);
941 var message = makeWarningMessage(validation);
942 if (typeof message === 'string') {
943 this.emitWarningMessage(message);
944 }
945 return input;
946 }
947
948 /**
949 * Emits a warning message, using `console.warn()` by default.
950 */
951
952 }, {
953 key: 'emitWarningMessage',
954 value: function emitWarningMessage(message) {
955 console.warn(message);
956 }
957 }, {
958 key: 'propTypes',
959 value: function propTypes(type) {
960 return makeReactPropTypes(type.unwrap());
961 }
962 }, {
963 key: 'match',
964 value: function match() {
965 for (var _len14 = arguments.length, args = Array(_len14), _key14 = 0; _key14 < _len14; _key14++) {
966 args[_key14] = arguments[_key14];
967 }
968
969 var clauses = args.pop();
970 if (!Array.isArray(clauses)) {
971 throw new Error('Invalid pattern, last argument must be an array.');
972 }
973 clauses;
974 var pattern = this.pattern.apply(this, babelHelpers.toConsumableArray(clauses));
975 return pattern.apply(undefined, args);
976 }
977 }, {
978 key: 'pattern',
979 value: function pattern() {
980 for (var _len15 = arguments.length, clauses = Array(_len15), _key15 = 0; _key15 < _len15; _key15++) {
981 clauses[_key15] = arguments[_key15];
982 }
983
984 var length = clauses.length;
985
986 var tests = new Array(length);
987 for (var i = 0; i < length; i++) {
988 var clause = clauses[i];
989 var annotation = this.getAnnotation(clause);
990 if (!annotation) {
991 if (i !== length - 1) {
992 throw new Error(`Invalid Pattern - found unannotated function in position ${ i }, default clauses must be last.`);
993 }
994 tests[i] = true;
995 } else {
996 invariant(annotation instanceof FunctionType || annotation instanceof ParameterizedFunctionType, 'Pattern clauses must be annotated functions.');
997 tests[i] = annotation;
998 }
999 }
1000 return function () {
1001 for (var _i = 0; _i < tests.length; _i++) {
1002 var test = tests[_i];
1003 var _clause = clauses[_i];
1004 if (test === true) {
1005 return _clause.apply(undefined, arguments);
1006 } else if (test.acceptsParams.apply(test, arguments)) {
1007 return _clause.apply(undefined, arguments);
1008 }
1009 }
1010 var error = new TypeError('Value did not match any of the candidates.');
1011 error.name = 'RuntimeTypeError';
1012 throw error;
1013 };
1014 }
1015 }, {
1016 key: 'refinement',
1017 value: function refinement(type) {
1018 var target = new RefinementType(this);
1019 target.type = type;
1020
1021 for (var _len16 = arguments.length, constraints = Array(_len16 > 1 ? _len16 - 1 : 0), _key16 = 1; _key16 < _len16; _key16++) {
1022 constraints[_key16 - 1] = arguments[_key16];
1023 }
1024
1025 target.addConstraint.apply(target, babelHelpers.toConsumableArray(constraints));
1026 return target;
1027 }
1028 }]);
1029 return TypeContext;
1030}();
1031
1032export { TypeContext as default };
\No newline at end of file