강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

비가싫어요님의 프로필 이미지
비가싫어요

작성한 질문수

Next + React Query로 SNS 서비스 만들기

[Next 15] Form 컴포넌트

SignupModal 타입 에러에 관해서 질문드립니다!

해결된 질문

작성

·

128

0

SignupModal 에서 에러가 하나 나오는데 관련해서 질문드립니다.

S2322: Type '(formData: FormData) =&gt; Promise&lt;{ message: string; } | undefined&gt;' is not assignable to type 'NonNullable&lt;string | ((formData: FormData) =&gt; void | Promise&lt;void&gt;) | undefined&gt;'.<br/>Type '(formData: FormData) =&gt; Promise&lt;{ message: string; } | undefined&gt;' is not assignable to type '(formData: FormData) =&gt; void | Promise&lt;void&gt;'.<br/>Type 'Promise&lt;{ message: string; } | undefined&gt;' is not assignable to type 'void | Promise&lt;void&gt;'.<br/>Type 'Promise&lt;{ message: string; } | undefined&gt;' is not assignable to type 'Promise&lt;void&gt;'.<br/>Type '{ message: string; } | undefined' is not assignable to type 'void'.<br/>Type '{ message: string; }' is not assignable to type 'void'.

이런 에러가 나옵니다. formData 의 타입이 정확하지 않아서 생기는 에러 같습니다. 근데 정상적으로 실행은 됩니다.

제 꺼에선 이렇게 에러가 나오는데 제로초님 화면에서는 에러가 나오는 것 같지 않아서 어떻게 그렇게 된 것인지 궁금해서 질문 남깁니다.

 

감사합니다.

답변 2

1

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

전체 코드 볼 수 있을까요? signupModal보다는 SignUp 모달 내부의 _lib/signup 같은 곳의 에러같아 보입니다.

원래 타입스크립트는 타입이 틀려도 실행이 됩니다 ㅎㅎ

export default function SignupModal() {
    const submit = async (formData: FormData) => {
        "use server";

        if (!formData.get('id')) {
            return { message: 'no_id'}
        }
        if (!formData.get('name')) {
            return { message: 'no_name'}
        }
        if (!formData.get('password')) {
            return { message: 'no_password'}
        }
        if (!formData.get('image')) {
            return { message: 'no_image'}
        }

        let shouldRedirect = false;
        try {
            const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/users`, {
                method: "POST",
                body: formData,
                credentials: 'include'
            })
            if (response.status === 403) {
                return { message: 'user exists' }
            }
            shouldRedirect = true;
        } catch(err) {
            console.error(err)
        }

        if (shouldRedirect) {
            redirect('/home')
        }
    }

    return (
        <>
            <div className={style.modalBackground}>
                <div className={style.modal}>
                    <div className={style.modalHeader}>
                        <BackButton />
                        <div>계정을 생성하세요.</div>
                    </div>
                    <Form action={submit}>
                        <div className={style.modalBody}>
                            <div className={style.inputDiv}>
                                <label className={style.inputLabel} htmlFor="id">아이디</label>
                                <input id="id" name="id" className={style.input} type="text" placeholder=""
                                       required
                                />
                            </div>
                            <div className={style.inputDiv}>
                                <label className={style.inputLabel} htmlFor="name">닉네임</label>
                                <input id="name" name="name" className={style.input} type="text" placeholder=""
                                       required
                                />
                            </div>
                            <div className={style.inputDiv}>
                                <label className={style.inputLabel} htmlFor="password">비밀번호</label>
                                <input id="password" name="password" className={style.input} type="password" placeholder=""
                                       required
                                />
                            </div>
                            <div className={style.inputDiv}>
                                <label className={style.inputLabel} htmlFor="image">프로필</label>
                                <input id="image" name="image" required className={style.input} type="file" accept="image/*"/>
                            </div>
                        </div>
                        <div className={style.modalFooter}>
                            <button className={style.actionButton}>가입하기</button>
                        </div>
                    </Form>
                </div>
            </div>
        </>)
}

여기있습니다! 제가 혹시 강의 보면서 빠뜨린 게 있을까요?

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

} catch(err) {
console.error(err)
return { message: '' }
} if (shouldRedirect) {
redirect('/home')
}
return { message: '' }

이렇게 리턴 추가하시면 됩니다.

const submit = async (formData: FormData) => {
    "use server";

    if (!formData.get('id')) {
        return { message: 'no_id'}
    }
    if (!formData.get('name')) {
        return { message: 'no_name'}
    }
    if (!formData.get('password')) {
        return { message: 'no_password'}
    }
    if (!formData.get('image')) {
        return { message: 'no_image'}
    }

    let shouldRedirect = false;
    try {
        const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/users`, {
            method: "POST",
            body: formData,
            credentials: 'include'
        })
        if (response.status === 403) {
            return { message: 'user exists' }
        }
        shouldRedirect = true;
    } catch(err) {
        console.error(err)
        return { message: ''}
    }

    if (shouldRedirect) {
        redirect('/home')
    }

    return { message: '' }
}

알려주신 방법으로 해 봤는데 일단 빨간줄이 계속 들어오네요. Form 컴포넌트의 action 쪽에 빨간줄이 있네요.

실행은 돼서 큰 지장은 없는 것 같은데 계속 빨간줄이 신경 쓰여서요 ㅋㅋㅋ

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

일단 다음 강의 때 한 번 더 컴포넌트를 수정하는 데 그러고 나서도 뜨는지 확인해보세요!

넵 그 때 한 번 더 확인해보겠습니다! 늦은 시간까지 빠른 답변 감사드립니다!

0

안녕하세요, 인프런 AI 인턴입니다.

비가싫어요님, 해당 타입 에러는 TypeScript에서 함수의 반환 타입이 올바르지 않기 때문에 발생하는 문제입니다. 에러 메시지를 보면, SignupModal의 함수가 { message: string } | undefined 타입의 Promise를 반환하고 있는데, 이는 void | Promise<void> 타입으로 변환되지 않기 때문에 에러가 발생하는 것입니다.

이 문제를 해결하기 위해서는 반환 타입을 명확히 설정해 주셔야 합니다. 즉, 함수가 반환하는 데이터 타입과 실제로 반환되는 값을 일치시켜야 합니다. 아래 몇 가지 팁을 제시합니다:

  1. 반환 타입 정의 명확히 하기: 함수가 어떤 값을 반환하는지 확인하고, 그에 맞도록 TypeScript 타입을 정의해 주세요. 예를 들어, 함수가 Promise<void>를 기대한다면, 함수 내의 실행 로직에서 불필요한 반환값이 없도록 하거나, 타입을 맞춰주는 것이 중요합니다.

  2. 입출력 타입 일치시키기: 함수의 입력과 출력 타입이 논리적으로 맞는지 확인하세요. TypeScript에서는 함수의 서명(매개변수 및 반환값)은 그 사용에 있어 매우 중요합니다.

  3. 제로초님의 코드를 참고: 질문에 제로초님의 코드에서는 에러가 없다는 언급이 있습니다. 제로초님의 강의 자료나 제공된 코드를 참고하여 본인의 코드와 비교해 보시면 도움이 될 것입니다.

관련 질문 URL:
- 타입스크립트 질문

이후에도 이러한 타입 관련 문제로 어려움이 있으시면, 강의나 공식 문서를 통해 타입스크립트의 함수 처리 및 타입 시스템에 관한 추가 학습을 권장드립니다.


저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

비가싫어요님의 프로필 이미지
비가싫어요

작성한 질문수

질문하기