μ λ€λ¦(Generic)μ΄λ?
Cλ μλ° κ°μ μ μ μΈμ΄μμ λ€μν νμ κ°μ μ¬μ¬μ©μ±μ λμ΄κΈ° μν΄ μ¬μ©νλ λ¬Έλ²μ΄λ€. νμ μ€ν¬λ¦½νΈλ μ μ νμ μ κ°μ§λ―λ‘ μ λ€λ¦ λ¬Έλ²μ μ§μνλ€.
μ λ€λ¦μ μ¬μ μ μλ―Έλ μΌλ°μ μΈ κ²(general)μ λ»νλλ°, νμ μ€ν¬λ¦½νΈμ μ λ€λ¦λ μ΄μ λΉμ·νκ² 'μΌλ°νλ λ°μ΄ν°' νμ μ΄λΌ λ³Ό μ μλ€.
μ λ€λ¦: ν¨μ, νμ , ν΄λμ€ λ±μμ λ΄λΆμ μΌλ‘ μ¬μ©ν νμ μ 미리 μ ν΄λμ§ μκ³ νμ λ³μλ₯Ό μ¬μ©ν΄μ ν΄λΉ μμΉλ₯Ό λΉμ λ λ€μμ, μ€μ λ‘ κ·Έ κ°μ μ¬μ©ν λ μΈλΆμμ νμ λ³μ μ리μ νμ μ μ§μ νμ¬ μ¬μ©νλ λ°©μ
-> μ΄λ κ² νλ©΄ ν¨μ, νμ , ν΄λμ€ λ± μ¬λ¬ νμ μ λν΄ νλνλ λ°λ‘ μ μνμ§ μμλ λκΈ° λλ¬Έμ μ¬μ¬μ©μ±μ΄ ν¬κ² ν₯μλλ€.
νμ λ³μλ μΌλ°μ μΌλ‘ <T>μ κ°μ΄ κΊΎμ κ΄νΈ λ΄λΆμ μ μλλ©°, μ¬μ©ν λλ ν¨μμ 맀κ°λ³μλ₯Ό λ£λ κ²κ³Ό μ μ¬νκ² μνλ νμ μ λ£μ΄μ€λ€.
νμ λ³μλͺ μΌλ‘ T(Type), E(Element), K(Key), V(Value) λ± ν κΈμλ‘ λ μ΄λ¦μ λ§μ΄ μ¬μ©νλ€.
anyμμ λΉκ΅
anyλ λ°°μ΄ μμλ€μ νμ μ΄ μ λΆ κ°μ§ μμ μ μμ§λ§,
μ λ€λ¦μ λ°°μ΄ μμ± μμ μ μνλ νμ μΌλ‘ νΉμ νλ€. μ¦, λ°°μ΄ μμκ° μ λΆ λμΌν νμ μΌλ‘ 보μ₯ν μ μλ€.
νμ μΆλ‘ κ³Ό κΈ°λ³Έκ° μ¬μ©
function exampleFunc<T>(arg: T): T[] {
return new Array(3).fill(arg);
}
exampleFunc("hello"); // Tλ stringμΌλ‘ μΆλ‘ λ¨
interface SubmitEvent<T = HTMLElement> extends SyntheticEvent<T> {submitter: T;} // κΈ°λ³Έκ° μ¬μ©
μ λ€λ¦ ν¨μλ₯Ό νΈμΆν λ νμ λͺ μ λΆλΆ(<>)μ μλ΅νλ©΄ μ»΄νμΌλ¬κ° μΈμλ₯Ό λ³΄κ³ νμ μ μΆλ‘ ν΄μ€λ€.
λν νΉμ μμ νμ μ μ μ μμ λλ μ λ€λ¦ νμ μ κΈ°λ³Έκ°μ μΆκ°ν μ μλ€.
μ£Όμμ
λ°°μ΄μλ§ μ‘΄μ¬νλ length μμ±μ μ λ€λ¦μμ μ°Έμ‘°νλ €κ³ νλ©΄ λΉμ°ν μλ¬κ° λ°μνλ€. μ»΄νμΌλ¬λ μ΄λ€ νμ μ΄ μ λ€λ¦μ μ λ¬λ μ§ μ μ μκΈ° λλ¬Έμ΄λ€.
μ΄λ΄ λλ μ λ€λ¦ κΊΎμ κ΄νΈ λ΄λΆμ 'length μμ±μ κ°μ§ νμ λ§ λ°λλ€'λΌλ μ μ½μ κ±Έμ΄μ€μΌλ‘μ¨ length μμ±μ μ¬μ©νκ²λ λ§λ€ μ μλ€.
interface TypeWithLength {
length: number;
}
function exampleFunc2<T extends TypeWithLength>(arg: T): number {
return arg.length;
}
νμΌ νμ₯μκ° tsxμΌ λ νμ΄ν ν¨μμ μ λ€λ¦μ μ¬μ©νλ©΄ μλ¬κ° λ°μνλ€.
tsxλ νμ μ€ν¬λ¦½νΈ + JSXμ΄λ―λ‘ μ λ€λ¦μ κΊΎμ κ΄νΈμ JSX νκ·Έμ κΊΎμ κ΄νΈλ₯Ό νΌλνμ¬ λ¬Έμ κ° μκΈ°λ κ²μ΄λ€!
μ λ€λ¦ λΆλΆμ extends ν€μλλ₯Ό μ¬μ©νμ¬ μ»΄νμΌλ¬μκ² νΉμ νμ μ νμ νμ λ§ μ¬ μ μμμ νμ€νκ² μλ €μ£Όλ©΄ λλ€.
λ³΄ν΅ μ λ€λ¦μ μ¬μ©ν λλ function ν€μλλ‘ μ μΈνλ κ²½μ°κ° λ§λ€.
// μλ¬ λ°μ: JSX element 'T' has no corresponding closing tag
const arrowExampleFunc = <T>(arg: T): T[] => {
return new Array(3).fill(arg);
}
// μλ¬ λ°μ X (κ°μ²΄ νμ
νμ₯)
const arrowExampleFunc2 = <T extends {}>(arg: T): T[] => {
return new Array(3).fill(arg);
};
μ λ€λ¦ μ¬μ©λ²
ν¨μμ μ λ€λ¦
μ΄λ€ ν¨μμ 맀κ°λ³μλ λ°ν κ°μ λ€μν νμ μ λ£κ³ μΆμ λ
function ReadOnlyRepository<T>(target: ObjectType<T> | EntitySchema<T> | string):
Repository<T> {
return getConnection("ro").getRepository(target);
}
// User μν°ν°μ μ½κΈ° μ μ© μ μ₯μλ₯Ό κ°μ Έμμ μ½κΈ° μ μ© μμ
μ μν
const userRepository = ReadOnlyRepository<User>(User);
νΈμΆ μκ·Έλμ²(call signature)μ μ λ€λ¦
νΈμΆ μκ·Έλμ²: νμ μ€ν¬λ¦½νΈμ ν¨μ νμ λ¬Έλ²μΌλ‘, ν¨μμ 맀κ°λ³μμ λ°ν νμ μ 미리 μ μΈνλ κ²
νΈμΆ μκ·Έλμ²λ₯Ό μ¬μ©ν λ μ λ€λ¦ νμ μ μ΄λμ μμΉμν€λμ§μ λ°λΌ νμ μ λ²μμ μ λ€λ¦ νμ μ μΈμ ꡬ체 νμ μΌλ‘ νμ ν μ§ κ²°μ ν μ μλ€.
export type UseRequesterHookType = <RequestData = void, ResponseData = void>(
baseURL?:
string | Headers,
defaultHeader?: Headers
) => [RequestStatus, Requester<RequestData, ResponseData>];
UseRequesterHookType νμ μ ν¨μλ₯Ό μ€μ νΈμΆν λ μ λ€λ¦ νμ μ ꡬ체 νμ μΌλ‘ νμ νλ€.
μμ²κ³Ό μλ΅ νμ μ΄ νΉμ νμ μΌλ‘ κ³ μ λμ§ μκ³ μν©μ λ§μΆ° λ³κ²½ κ°λ₯ν΄μ§λ€.
μ λ€λ¦ ν΄λμ€
μ λ€λ¦ ν΄λμ€: μΈλΆμμ μ λ ₯λ νμ μ ν΄λμ€ λ΄λΆμ μ μ©ν μ μλ ν΄λμ€
μ λ€λ¦ ν΄λμ€λ₯Ό μ¬μ©νλ©΄ ν΄λμ€ μ 체μ κ±Έμ³ νμ 맀κ°λ³μκ° μ μ©λλ€.
class Box<T> {
private _value: T;
constructor(value: T) {
this._value = value;
}
getValue(): T {
return this._value;
}
setValue(value: T): void {
this._value = value;
}
}
// Box<string> νμ
μ κ°μ²΄ μμ±
const stringBox = new Box<string>("Hello, world!");
console.log(stringBox.getValue()); // μΆλ ₯: Hello, world!
// Box<number> νμ
μ κ°μ²΄ μμ±
const numberBox = new Box<number>(42);
console.log(numberBox.getValue()); // μΆλ ₯: 42
νΉμ λ©μλλ§μ λμμΌλ‘ μ λ€λ¦μ μ μ©νλ €λ©΄ ν΄λΉ λ©μλλ₯Ό μ λ€λ¦ λ©μλλ‘ μ μΈνλ©΄ λλ€.
class Utility {
static identity<T>(value: T): T {
return value;
}
}
// identity λ©μλ νΈμΆ μ νμ
μ μ§μ
console.log(Utility.identity<string>("TypeScript")); // μΆλ ₯: TypeScript
console.log(Utility.identity<number>(123)); // μΆλ ₯: 123
μ νλ μ λ€λ¦
μ νλ μ λ€λ¦: νμ 맀κ°λ³μμ λν μ μ½ μ‘°κ±΄μ μ€μ νλ κΈ°λ₯
μ νλ μ λ€λ¦μ μ¬μ©νλ©΄ νμ μμ μ±μ κ°ννλ©΄μλ μ μ°ν νμ₯μ΄ κ°λ₯νλ€.
type ErrorRecord<Key extends string> =
Exclude<Key, ErrorCodeType> extends never
? Partial<Record<Key, boolean>>
: never;
λ°μ΄λ νμ 맀κ°λ³μ(bounded type parameters): νμ 맀κ°λ³μκ° νΉμ νμ μΌλ‘ λ¬Άμμ λ(bind) ν€λ₯Ό μ§μΉ
κ·Έλ¦¬κ³ μ¬κΈ°μ stringμ ν€μ μν νκ³(upper bound)λΌκ³ νλ€.
μμ λ°μ μ μλ νμ μΌλ‘λ κΈ°λ³Έ νμ λΏλ§ μλλΌ μν©μ λ°λΌ μΈν°νμ΄μ€λ ν΄λμ€λ μ¬μ©ν μ μλ€.
λν μ λμ¨ νμ μ μμν΄μ μ μΈν μλ μλ€.
νμ₯λ μ λ€λ¦
μ λ€λ¦ νμ μ μ¬λ¬ νμ μ μμλ°μ μ μμΌλ©° νμ 맀κ°λ³μλ₯Ό μ¬λ¬ κ° λ μλ μλ€.
<Key extends string> μ΄λ° μμΌλ‘ νμ μ μ μ½νλ©΄ μ λ€λ¦μ μ μ°μ±μ μμ΄λ²λ¦°λ€.
μ λ€λ¦μ μ μ°μ±μ μμ§ μμΌλ©΄μ νμ μ μ μ½ν΄μΌ ν λλ νμ 맀κ°λ³μμ μ λμ¨ νμ μ μμν΄μ μ μΈνλ©΄ λλ€.
<Key extends string | number>
μ λμ¨ νμ μΌλ‘ Tκ° μ¬λ¬ νμ μ λ°κ² ν μλ μμ§λ§, νμ 맀κ°λ³μκ° μ¬λ¬ κ°μΌ λλ μ²λ¦¬ν μ μλ€. μ΄λ΄ λλ 맀κ°λ³μλ₯Ό νλ λ μΆκ°νμ¬ μ μΈνλ€.
export class APIResponse<Ok, Err = string>{
private readonly data: Ok | Err | null;
private readonly status: ResponseStatus;
private readonly statusCode: number | null;
// ...
}
μ λ€λ¦ μμ
μ λ€λ¦μ μ₯μ μ λ€μν νμ μ λ°κ² ν¨μΌλ‘μ¨ μ½λλ₯Ό ν¨μ¨μ μΌλ‘ μ¬μ¬μ©νλ κ²μ΄λ€.
νμ μμ κ°μ₯ λ§μ΄ μ λ€λ¦μ΄ νμ©λλ κ³³μ, API μλ΅ κ°μ νμ μ μ§μ ν λμ΄λ€.
export interface MobileApiResponse<Data> {
data: Data;
statusCode: string;
statusMessage?: string;
}
export const fetchPriceInfo = (): Promise<MobileApiResponse<PriceInfo>> => {
// ...
};
export const fetchOrderInfo = (): Promise<MobileApiResponse<Order>> => {
// ...
};
API μλ΅ κ°μ λ°λΌ λ¬λΌμ§λ dataλ₯Ό μ λ€λ¦ νμ Dataλ‘ μ μΈνμ¬ μΈν°νμ΄μ€ MobileApiResponseλ₯Ό λ§λ€μλ€.
λ€μν API μλ΅ κ°μ νμ μ MobileApiResponseλ₯Ό νμ©ν΄μ μ½λλ₯Ό ν¨μ¨μ μΌλ‘ μ¬μ¬μ©ν μ μλ€.
μ λ€λ¦μ κ΅³μ΄ μ¬μ©νμ§ μμλ λλ νμ
μ λ€λ¦μ νμν κ³³μ μ¬μ©νλ©΄ κ°λ μ±κ³Ό ν¨μ¨μ±μ λμΌ μ μμ§λ§,
νμνμ§ μμ κ³³μ μ λ€λ¦μ μ¬μ©νλ©΄ μ½λ κΈΈμ΄λ§ λμ΄λκ³ κ°λ μ±μ ν΄μΉ μ μλ€.
// λΆνμν μ λ€λ¦
type GType<T> = T;
type RequirementType = "USE" | "UN_USE" | "NON_SELECT";
interface Order {
getRequirement(): GType<RequirementType>;
}
// μλμ κ°λ€
type RequirementType = "USE" | "UN_USE" | "NON_SELECT";
interface Order {
getRequirement(): RequirementType;
}
κ΅³μ΄ μ λ€λ¦μ μ¬μ©νμ§ μκ³ νμ 맀κ°λ³μλ₯Ό κ·Έλλ‘ μ μΈνλ κ²κ³Ό κ°μ κΈ°λ₯μ΄λ€.
any μ¬μ©
anyλ₯Ό μ¬μ©νλ©΄ μ λ€λ¦μ μ₯μ (μ¬μ¬μ©μ±)κ³Ό νμ μΆλ‘ λ° νμ κ²μ¬λ₯Ό ν μ μλ μ΄μ μ λ릴 μ μκ² λλ€.
any νμ μ λͺ¨λ νμ μ νμ©νκΈ° λλ¬Έμ μ¬μ€μ μλ°μ€ν¬λ¦½νΈμ λμΌν λ°©μμ΄λ©°, μ λ€λ¦μ ν¬ν¨ν΄ νμ μ μ§μ νλ μλ―Έκ° μ¬λΌμ§κ² λλ€.
κ°λ μ±μ κ³ λ €νμ§ μμ μ¬μ©
μ λ€λ¦μ΄ κ³Όνκ² μ¬μ©λλ©΄ κ°λ μ±μ ν΄μΉκΈ° λλ¬Έμ μ½λλ₯Ό μ½κ³ νμ μ μ΄ν΄νκΈ° μ΄λ €μμ§λ€.
볡μ‘ν μ λ€λ¦μ μλ―Έ λ¨μλ‘ λΆν ν΄μ μ¬μ©νλ κ² μ’λ€.
ref. μ°μν νμ μ€ν¬λ¦½νΈ with 리μ‘νΈ - μ λ€λ¦ ννΈ