Typescript에서 타이머 함수 사용 시 타입 에러 해결: 실행 환경에 따른 타입 지정

soo·2024년 5월 11일
1

ErrorLog

목록 보기
2/6
post-thumbnail

🔒 배경

타이머 구현 과정에서 시간 감소를 구현하기 위해 setInterval 함수를 사용했다.

useEffect(() => {
	let timer: number | undefined;
	// ... 기타 로직

	if (!isPause && !isShow && timeLeft > 0) {
		timer = setInterval(() => {
			setTimeLeft((prevTime) => prevTime - 1000);
		}, 1000);
	}

	return () => {
		if (timer) clearInterval(timer);
	};

위 코드를 구현하니 아래와 같이 Timer는 number 타입에 할당할 수 없다는 에러가 발생했다.

🔓 원인

setInterval 함수의 타입에 대해 찾아본 결과, 실행 환경에 따라 달라질 수 있다는 것을 알게 되었다.

setInterval의 타입

브라우저 환경에서는 number 타입을 반환하지만, Node.js 환경에서는 NodeJS.Timeout 객체를 반환한다.

TypeScript를 설치하면 기본적으로 브라우저와 Node.js 환경 모두에 대한 타입 정의가 포함된다. 따라서 TypeScript는 setInterval 함수가 Node.js 환경에서도 사용될 수 있다고 가정하고, 이에 맞는 타입을 요구하게 된다. 이로 인해 Node.js 환경에서의 반환 타입인 NodeJS.Timeout과 브라우저 환경에서의 반환 타입인 number 간의 불일치로 인해 에러가 발생한다.

🔐 해결 방법

setInterval을 호출할 때 window.setInterval을 사용하여 브라우저 환경에서 사용한 함수임을 명시적으로 지정해주었다. 이렇게 하면 TypeScript는 해당 함수가 브라우저 환경에서 사용된다고 인식하고, 반환 타입을 number로 간주한다.

useEffect(() => {
	let timer: number | undefined;
	// ... 기타 로직

	if (!isPause && !isShow && timeLeft > 0) {
		timer = window.setInterval(() => {
			setTimeLeft((prevTime) => prevTime - 1000);
		}, 1000);
	}

	return () => {
		if (timer) clearInterval(timer);
	};

위 방법 이외에도 setInterval 함수가 반환하는 타입을 브라우저와 Node.js 환경 모두에서 호환 가능하도록 아래와 같이 지정해 줄 수있다.

let timer: ReturnType<typeof setInterval> | undefined;

위와 같이 지정해주면 브라우저 환경에서는 number 타입이, Node.js 환경에서는 NodeJS.Timeout 타입이 할당되어 타입 에러가 발생하지 않는다.

setInterval 함수 이외에 setTimeout, clearTimeout 등의 타이머 관련 함수들도 환경에 따라 다른 타입을 반환한다. 이러한 함수들을 사용할 때 반환 타입을 명확히 정의하거나, 특정 환경에서 사용함을 명시적으로 지정하여 타입 안정성을 유지하는 것이 중요할 것 같다..!

profile
재미있게 영차영차 🌱

0개의 댓글