Skip to content

Conversation

@kss761036
Copy link
Collaborator

요구사항

기본

  • 스프린트 미션 5 ~ 7에 대해 typescript를 적용해주세요

심화

  • any타입을 최소한으로 써주세요

멘토에게

@kss761036 kss761036 requested a review from kich555 January 10, 2025 08:15
@kss761036 kss761036 added the 순한맛🐑 마음이 많이 여립니다.. label Jan 10, 2025
name: ItemInputQuery;
className: string;
//value: string | File;
value: any;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래 주석처럼 쓰고싶었지만, File과 string을 구분하는 곳에 오류를 해결하는 방법을 못찾았습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

보시면 value의 타입에러가 발생하지만 타입가드 함수는 type === "textarea" 와 같이 type을 사용하죠?
이런 방식으로 value의 타입이 추론되게끔 하려면 인터페이스를 다시 구성해야합니다

import { ItemInputQuery } from "./Query";

type ItemInputValue = FileTypeValue | TextareaTypeValue;

type FileTypeValue = {
  labelName: string;
  type: "file";
  id: string;
  name: ItemInputQuery;
  className: string;
  value: File;
  //onChange: () => void;
  onChange: any;
  placeholder?: string;
};

type TextareaTypeValue = {
  labelName: string;
  type: "textarea";
  id: string;
  name: ItemInputQuery;
  className: string;
  value: string;
  //onChange: () => void;
  onChange: any;
  placeholder?: string;
};

export default ItemInputValue;

이렇게 union타입을 활용하는것 처럼요

추가로 설명드리자면 이미지처럼 type이 textarea 나 file처럼 특정한 string을 가지고 있는 타입이라면
단순 string타입으로 퉁치는 것 보다

type type = 'textarea' | 'file'

이렇게 union타입을 활용하는걸 추천드립니다. 내가 타입을 좁힐수록 추론은 더욱 잘 됩니다.

//value: string | File;
value: any;
//onChange: () => void;
onChange: any;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 위와 비슷한데 해결방법을 모르겠습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 처럼 하면 이 부분에서도 에러가 발생하지 않을거에요 ㅎ

return (
<li key={el.id}>
<div className="comment_menu">
<button type="button" className="btn_reset" data-menu="button" onClick={() => handleCommentMenu(el.id as any)}>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 버튼은 메뉴가 숨겨져있는 토글버튼인데,
아래 주석이 타입스크립트도 오류가 없고 깔끔해서 맞는거같은데 이상하게 토글버튼이 작동을 안합니다.
타입스크립트와 큰 관련이 없는거같은데 String이 이 아닌 as any 를 사용하면 작동을 합니다.
이유가 뭘까요??

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Props 타입은 id라는 key값을 가진 객체입니다

const handleCommentMenu = (id: Props) => {
    setCommentMenu((prev) => (prev === id ? null : id));
  };

이 함수부터가 잘못된거같은데요? 함수에서는 id파라미터를 마치 string타입처럼 사용하고있잖아요

const [commentMenu, setCommentMenu] = useState<Props | null>(null);

상태의 사용도 마찬가지구요 이건 다시한번 체크해보셔야할것 같네요

Copy link
Collaborator

@kich555 kich555 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳 잘하셨네요 ㅎㅎ

}

const DetailBtm = ({ id }: Props) => {
const [commentMenu, setCommentMenu] = useState<Props | null>(null);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 const [commentMenu, setCommentMenu] = useState<string | null>(null);

이렇게 바꿔야하지 않을까요? 확신할 순 없는데
아래에서 해당 상태를 사용하는걸 보면 id값과 비교하는데 사용하네요


const DetailTop = ({ id }) => {
const { data, loading, error } = useApi(`${id}`);
interface ProductDetail extends Product {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends 사용해보신것 좋습니다 ㅎㅎ

Comment on lines 9 to 22

const useApi = (url) => {
const [data, setData] = useState(null);
const useApi = <T,>(url: string) => {
const [data, setData] = useState<T | null>(null);

const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [error, setError] = useState<AxiosError | null>(null);
useEffect(() => {
const fetchProduct = async () => {
try {
const response = await api.get(url);
const response = await api.get<T>(url);
setData(response.data);
} catch (error) {
setError(error);
setError(error as AxiosError);
} finally {
setLoading(false);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍👍

@kich555 kich555 merged commit b23e938 into codeit-bootcamp-frontend:React-김승석 Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

순한맛🐑 마음이 많이 여립니다..

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants