function clearTimer(clock, timerId, ttype) {
				if (!timerId) {
					// null appears to be allowed in most browsers, and appears to be
					// relied upon by some libraries, like Bootstrap carousel
					return;
				}

				if (!clock.timers) {
					clock.timers = {};
				}

				// in Node, the ID is stored as the primitive value for `Timeout` objects
				// for `Immediate` objects, no ID exists, so it gets coerced to NaN
				const id = Number(timerId);

				if (Number.isNaN(id) || id < idCounterStart) {
					const handlerName = getClearHandler(ttype);

					if (clock.shouldClearNativeTimers === true) {
						const nativeHandler = clock[`_${handlerName}`];
						return typeof nativeHandler === "function"
							? nativeHandler(timerId)
							: undefined;
					}
					warnOnce(
						`FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.` +
						"\nTo automatically clean-up native timers, use `shouldClearNativeTimers`."
					);
				}

				if (clock.timers.hasOwnProperty(id)) {
					// check that the ID matches a timer of the correct type
					const timer = clock.timers[id];
					if (
						timer.type === ttype ||
						(timer.type === "Timeout" && ttype === "Interval") ||
						(timer.type === "Interval" && ttype === "Timeout")
					) {
						delete clock.timers[id];
					} else {
						const clear = getClearHandler(ttype);
						const schedule = getScheduleHandler(timer.type);
						throw new Error(
							`Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`
						);
					}
				}
			}
@param {Clock} clock
@param {number} timerId
@param {string} ttype