https://www.typescriptlang.org/ko/docs/handbook/2/generics.html
단일 타입이 아닌, 다양한 타입을 동적으로 정의할 수 있음.
코드의 재사용성과 유연성 증가, 코드를 추상화된 형태로 작성할 수 있게 됨
1. 제네릭 함수
function identity<T>(arg: T): T {
return arg;
}
let result1: number = identity<number>(42); // result1의 타입은 number
let result1: number = identity(42); // 타입 추론 사용
let result2: string = identity<string>("hello"); // result2의 타입은 string
let result2: string = identity("hello"); // 타입 추론 사용
- <T> 제네릭 타입 매개변수 : 꺽쇠를 변수명,함수명 앞에 쓰면 "타입 단언"이 된다.
- (arg : T) : 함수의 매개변수는 T타입이여서, 어떤 타입의 인수라도 받을 수 있음
- :T : 함수의 리턴값에 대한 타입 정의
function loggingIdentity<T>(arg: T[]): T[] {
return arg;
}
let result1: number[] = loggingIdentity([1, 2, 3]);
let result2: string[] = loggingIdentity(["a", "b", "c"]);
// 타입 추론 사용됨. 때문에 loggingIdentity<number[]>([1, 2, 3]); <- 불필요
- <T> 제네릭 타입 매개변수 : <T>을 통해 어떤 타입의 배열을 받을지 동적으로 결정할 수 있음
- (arg: T[]) :함수의 매개변수는 T타입이여서,배열의 원소들이 어떤 타입이라도 받을 수 있음
- T[] :함수의 리턴값에 대한 타입 정의, 받은 타입과 동일한 타입의 배열을 반환함.
2. 함수를 값으로 쓰기
- 변수에 함수 할당할 때 유용
- 함수 자체를 매개변수로 전달할 때 유용
myIdentity라는 변수에 identity 함수를 할당하는 코드
: myIdentity 변수는 identity 함수와 동일한 함수 타입을 갖게 됨.
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = identity; // 일반 js라면, let myIdentity = identity함수
let result1: number = myIdentity(42); // result1의 타입은 number
let result2: string = myIdentity("hello"); // result2의 타입은 string
3. 제네릭 인터페이스
interface Pair<K, V> {
key: K;
value: V;
}
// 문자열과 숫자를 담은 Pair 인스턴스
let keyValue: Pair<string, number> = { key: "age", value: 25 };
// 문자열과 불린형을 담은 Pair 인스턴스
let keyValue: Pair<string, boolean> = { key: "admin", value: true };
- Pair는 제네릭 인터페이스 : K,V을 타입 매개변수로 받아 동적으로 타입이 결정됨
- Pair<string , number> : Paire<K,V>에 타입 매개변수가 할당됨
4. html요소의 기본 속성을 확장하기 위한 제네릭
// 부모 컴포넌트 App.tsx
<AssetImage image={item.image} className="prods-img" />
// 자식 컴포넌트 AssetImage.tsx
import { HTMLProps } from "react";
interface AssetImageProps extends HTMLProps<HTMLImageElement> {
image?: string;
}
function AssetImage({ image, ...props }: AssetImageProps) {
return <img src={imageUrl} {...props} />;
}
export default AssetImage;
- AssetImageProps 인터페이스가 HTMLImageElement 요소에 대한 모든 속성을 상속한 것임
이미지 엘리먼트에 사용되는 모든 표준 HTML 속성을 AssetImageProps에서도 사용할 수 있게 됨
Promise<T>
: 제네릭을 어디에 붙여야 하는지 어떻게 앎? prmise에 제네릭을 붙여야 한다는걸 어떻게 파악?
export interface GetManyResponse<T> {
docs: T[];
include?: any;
limit: number;
totalDocs: number;
}
export const useGetManyProduct = (prodQuery: ProductQueryParams) => {
return useQuery({
placeholderData: keepPreviousData, // https://tanstack.com/query/v5/docs/react/guides/paginated-queries <- layout shifting이 일어나지 않아, 레이아웃이 깨지지 않는다.
// [제네릭] 2
queryFn: (): Promise<GetManyResponse<Product>> => {
return axiosInstance({
method: "get",
params: prodQuery,
url: `/product`
}).then((res) => res.data);
},
queryKey: ProductQuery.getMany(prodQuery) // ['all','getMany',{sort:price, title[match] :'Women'}]
// refetchOnWindowFocus: isRefecth, // 탭을 나갔다가 다시 탭 눌렀을때, stale됐으면 자동으로 refetch되는 기능
});
};
'프론트엔드 > Typescript' 카테고리의 다른 글
타입스크립트의 필요성에 대해 (1) | 2025.01.05 |
---|