코드를 짜다가 아래와 같은 문제가 발생했다.
예약 테이블에 데이터를 추가할 때 타입 에러가 발생하는 문제이다.
여기서 이상한 점은 Omit으로 id와 created_at을 제외시켜도
다른 속성들이 타입이 명시되지 않았다고 한다.
Omit을 하고자하는 데이터에는 'check_in_date' 데이터 타입이
명시되어 있는데 왜 안되는지 의문이였다.
No overload matches this call.
Overload 2 of 2, '(values: Omit<{ camp_area_id: string; check_in_date: string; check_out_date: string; client_name: string; client_phone: string; created_at: string; fee: number; id: string; payment_method: string; people: number; user_id: string; }, "created_at" | "id">[], options?: { ...; } | undefined): PostgrestFilterBuilder<...>', gave the following error.
Object literal may only specify known properties, and 'check_in_date' does not exist in type 'Omit<{ camp_area_id: string; check_in_date'
문제가 발생한 코드)
데이터를 추가할 때 필요한 데이터 속성들을 1개씩 지워서
확인해도 다른 데이터 속성에서도 똑같은 오류가 발생하고 있었다.
type UserInfo = { people: number; name: string; phone: string };
type Reservation = Tables<'reservation'>;
const currentDate = new Date();
const [dates, setDates] = useState<[Date, Date]>([
new Date(currentDate.setHours(0, 0, 0, 0)),
new Date(
currentDate?.getFullYear()!,
currentDate?.getMonth()!,
currentDate?.getDate()! + 1,
),
const ReservationForm = ({ reservation }: { reservation: ReservationInfo }) => {
const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<UserInfo>({
defaultValues: { people: 1, name: '', phone: '' },
mode: 'onChange',
});
const methods = ['카카오페이', '휴대폰', '카드', '실시간 계좌이체'];
const [isActive, setIsActive] = useState<number | null>(null);
const [isOpenConfirm, setIsOpenConfirm] = useState<boolean>(false);
const [isOpenComplete, setIsOpenComplete] = useState<boolean>(false);
const [dates, setDates] = useState<[Date, Date]>([new Date(), new Date()]);
const [nights, setNights] = useState<number>(1);
const toggleActive = (selectMethod: number) => {
if (isActive == selectMethod) setIsActive(null);
else setIsActive(selectMethod);
};
const params = useSearchParams();
const campAreaId = params.get('id');
const { max_people, price, name } = reservation!;
const { check_in, check_out } = reservation?.camp!;
const { data: session } = useSession();
const onSubmit: SubmitHandler<UserInfo> = async (userInfo) => {
const { data, error } = await supabase
.from('reservation')
.insert<Omit<Reservation, 'created_at'|'id'>>({
check_in_date: dates[0],
check_out_date: dates[1],
client_name: userInfo.name,
client_phone: userInfo.phone,
fee: price * nights,
user_id: session?.user.id,
people: userInfo.people,
camp_area_id: campAreaId,
payment_method: methods[isActive!],
})
.select();
if (data) {
setIsOpenComplete(true);
console.log('데이터 등록 완료!');
}
if (error) console.log('error', error);
};
};
export default ReservationForm;
1번째 시도)
supabase 예약 테이블에서 데이터를 추가할 때 데이터를 추가 시
필요한 데이터 타입을 명시해 작성해 보았다.
이 해결방안으로는 문제가 해결되지 않았다.
체크인/체크아웃 날짜 데이터 타입은 문자열로 인식하는데
체크인/체크아웃 날짜를 Date 형식으로 선언해서 값을 저장하다보니
데이터 타입 문제가 확실하다고 느꼈다.
import { Database, Tables } from '@/types/supabase';
type ReservationInsert = Database['public']['Tables']['reservation']['Insert'];
const onSubmit: SubmitHandler<UserInfo> = async (userInfo) => {
const { data, error } = await supabase
.from('reservation')
.insert<ReservationInsert>({
check_in_date: dates[0],
check_out_date: dates[1],
client_name: userInfo.name,
client_phone: userInfo.phone,
fee: price * nights,
user_id: session?.user.id,
people: userInfo.people,
camp_area_id: campAreaId,
payment_method: methods[isActive!],
})
.select();
2번째 시도)
데이터를 추가할 때 임의의 데이터로 직접 넣어보면서 어느 부분이
문제가 있는지 확인한다. 그 결과 날짜 부분과 유저 아이디 부분에서
타입 오류가 발생한 사실을 알게되었다.
const { data, error } = await supabase
.from('reservation')
.insert({
camp_area_id: '123',
check_in_date: dates[0],
check_out_date: dates[1],
client_name: userInfo.name,
client_phone: userInfo.phone,
fee: price * nights,
payment_method: methods[isActive!],
people: userInfo.people,
user_id: session?.user?.id,
})
.select();
💡 해결한 코드)
체크인/체크아웃 날짜를 문자열로 변환하고 유저 아이디도
문자열로 단언해주니 문제가 완전히 해결되었다!
const onSubmit: SubmitHandler<UserInfo> = async (userInfo) => {
const { data, error } = await supabase
.from('reservation')
.insert({
camp_area_id: campAreaId,
check_in_date: dates[0].toISOString(),
check_out_date: dates[1].toISOString(),
client_name: userInfo.name,
client_phone: userInfo.phone,
fee: price * nights,
payment_method: methods[isActive!],
people: userInfo.people,
user_id: session?.user?.id as string,
})
.select();