function likelyHasTypo( type, loc ) {
		var replacement;
		var typedef;
		var elem;
		var j;

		if ( type.type === 'OptionalType' ) {
			// Need to go down one more level for optional parameters:
			type = type.expression;
		}
		if ( type.type === 'TypeApplication' ) {
			// Case: type definition with angle brackets such as Array<number>
			typedef = type.expression.name;
			replacement = correctTypedef( typedef );
			if ( replacement ) {
				report( typedef, replacement, loc );
			}
			return likelyHasTypo( type.applications[ 0 ], loc );
		}
		if (
			type.type === 'AllLiteral' ||
			type.type === 'NullLiteral' ||
			type.type === 'UndefinedLiteral'
		) {
			// Return early for wildcard (`*`), `undefined`, and `null`:
			return;
		}
		if ( type.type === 'UnionType' ) {
			// Check individual types of type unions (e.g., `(Date|string)`)...
			for ( j = 0; j < type.elements.length; j++ ) {
				elem = type.elements[ j ];
				if ( elem.type === 'TypeApplication' ) {
					typedef = elem.expression.name;
					replacement = correctTypedef( typedef );
					if ( replacement ) {
						report( typedef, replacement, loc );
					}
					likelyHasTypo( elem.applications[ 0 ], loc );
				} else if (
					elem.type !== 'AllLiteral' &&
					elem.type !== 'NullLiteral' &&
					elem.type !== 'UndefinedLiteral'
				) {
					typedef = elem.name;
					replacement = correctTypedef( typedef );
					if ( replacement ) {
						report( typedef, replacement, loc );
					}
				}
			}
			return;
		}
		typedef = type.name;
		if ( typedef ) {
			replacement = correctTypedef( typedef );
			if ( replacement ) {
				report( typedef, replacement, loc );
			}
		}
	}
Checks and reports whether a type definition likely has a typo.

@private
@param {Object} type - type definition
@param {Object} loc - lines of code (object with `start` and `end` properties)
@returns {void}