LearningTS Chapter 10 - YDP-SPLOUNGE-CLUB/typescript-study GitHub Wiki
νμ μ€ν¬λ¦½νΈμμ ν¨μμ κ°μ ꡬ쑰체λ μ λ€λ¦ νμ ꡬ쑰체λ₯Ό μνλ μλ§νΌ μ μΈν μ μλ€. μ λ€λ¦ νμ λ§€κ°λ³μλ μ λ€λ¦ ꡬ쑰체μ κ° μ¬μ©λ²μ λ°λΌ νμ μ΄ κ²°μ λλ€. μ΄λ¬ν νμ λ§€κ°λ³μλ ꡬ쑰체μ κ° μΈμ€ν΄μ€μμ μλ‘ λ€λ₯Έ μΌλΆ νμ μ λνλ΄κΈ° μν΄ κ΅¬μ‘°μ²΄μ νμ μΌλ‘ μ¬μ©λλ€.
μ΄λ¬ν νμ λ§€κ°λ³μλ ꡬ쑰체μ κ° μΈμ€ν΄μ€μμ μλ‘ λ€λ₯Έ μΌλΆ νμ μ λνλ΄κΈ° μν΄ κ΅¬μ‘°μ²΄μ νμ μΌλ‘ μ¬μ©λλ€.
νμ λ§€κ°λ³μλ ꡬ쑰체μ κ° μΈμ€ν΄μ€μ λν΄ νμ μΈμλΌκ³ νλ μλ‘ λ€λ₯Έ νμ μ ν¨κ» μ 곡ν μ μμ§λ§ νμ μΈμκ° μ 곡λ μΈμ€ν΄μ€ λ΄μμλ μΌκ΄μ±μ μ μ§νλ€.
νμ λ§€κ°λ³μλ μ νμ μΌλ‘ T λ U κ°μ λ¨μΌ λ¬Έμ μ΄λ¦ λλ Key Value κ°μ νμ€μΉΌ μΌμ΄μ€ μ΄λ¦μ κ°λλ€.
λ§€κ°λ³μ κ΄νΈ λ°λ‘ μ ννμ΄κ΄νΈ(<, >) λ‘ λ¬ΆμΈ νμ λ§€κ°λ³μμ λ³μΉμ λ°°μΉν΄ ν¨μλ₯Ό μ λ€λ¦μΌλ‘ λ§λ λ€.
κ·Έλ¬λ©΄ ν΄λΉ νμ λ§€κ°λ³μλ₯Ό ν¨μμ λ³Έλ¬Έ λ΄λΆμ λ§€κ°λ³μ νμ μ λν μ΄μ , λ°ν νμ μ λν μ΄μ , νμ μ λν μ΄μ μ μ¬μ©ν μ μλ€.
function identity<T>(input: T) {
return input;
}
const numberic = identity("me"); // νμ
: me;
const stringy = identity(123); // νμ
: 123;const identity = <T>(input: T) => input;
identity(123); // νμ
:123μμμ μμ νμ λ§€κ°λ³μλ₯Ό μΌνλ‘ κ΅¬λΆν΄ ν¨μλ₯Ό μ μνλ€. μ λ€λ¦ ν¨μμ κ° νΈμΆμ κ° νμ λ§€κ°λ³μμ λν μ체 κ° μ§ν©μ νμΈν μ μλ€.
ν¨μκ° μ¬λ¬ κ°μ νμ λ§€κ°λ³μλ₯Ό μ μΈνλ©΄ ν΄λΉ ν¨μμ λν νΈμΆμ λͺ μμ μΌλ‘ μ λ€λ¦ νμ μ λͺ¨λ μ μΈνμ§ μκ±°λ λͺ¨λ μ μΈν΄μΌ νλ€.
function makeTuple<First, Second>(fist: First, second: Second) {
return [fist, second] as const;
}μΈν°νμ΄μ€λ μ λ€λ¦μΌλ‘ μ μΈν μ μλ€. μΈν°νμ΄μ€λ ν¨μμ μ μ¬ν μ λ€λ¦ κ·μΉμ λ°λ₯΄λ©° μΈν°νμ΄μ€ μ΄λ¦ λ€ <κ³Ό > μ¬μ΄μ μ μΈλ μμμ μμ νμ λ§€κ°λ³μλ₯Ό κ°λλ€.
interface Box<T> {
inside: T;
};
let stringBox: Box<string> = {
inside: 'abc',
}
let numberBox: Box<number> = {
inside: 1111,
}μ¬λ°λ μ¬μ€μ νμ μ€ν¬λ¦½νΈμμ λ΄μ₯ Array λ©μλλ μ λ€λ¦ μΈν°νμ΄μ€λ‘ μ μλλ€λ μ μ΄λ€.
μ λ€λ¦ ν¨μμ λ§μ°¬κ°μ§λ‘ μ λ€λ¦ μΈν°νμ΄μ€μ νμ μΈμλ μ¬μ©λ²μμ μ μΆν μ μλ€.
interface LinkedNode<Value> {
next?: LinkedNode<Value>;
value: Value;
}
function getLast<Value>(node: LinkedNode<Value>): Value {
return node.next ? getLast(node.next) : node.value;
}
// μ μΆλ Value νμ
: Date
let lastDate = getLast({
value: new Date("09-13-1993");
});μΈν°νμ΄μ€ μ²λΌ ν΄λμ€λ λμ€μ λ©€λ²μμ μ¬μ©ν μμμ μμ νμ λ§€κ°λ³μλ₯Ό μ μΈν μ μλ€. ν΄λμ€μ κ° μΈμ€ν΄μ€λ νμ λ§€κ°λ³μλ‘ κ°μ λ€λ₯Έ νμ μΈμ μ§ν©μ κ°μ§λ€.
class Secret<Key, Value> {
key: Key;
value: Value;
constructor(key: Key, value: Value) {
this.key = key;
this.value = value;
}
getValue(key: Key): Value | undefined {
return this.key === key ? this.value : undefined;
}
}μ λ€λ¦ ν΄λμ€ μΈμ€ν΄μ€νλ μ λ€λ¦ ν¨μλ₯Ό νΈμΆνλ κ²κ³Ό λμΌν νμ μΈμ μ μΆ κ·μΉμ λ°λ₯Έλ€.
ν¨μ μμ±μμ μ λ¬λ λ§€κ°λ³μμ νμ μΌλ‘λΆν° νμ μΈμλ₯Ό μ μΆλ₯Ό ν μ μλ€λ©΄ μ μΆλ νμ μ μ¬μ©νλ€.
νμ§λ§ μμ±μμ μ λ¬λ μΈμμμ ν΄λμ€ νμ μΈμλ₯Ό μ μΆν μ μλ κ²½μ°μλ νμ μΈμμ κΈ°λ³Έκ°μ unknown μ΄ λλ€.
class CurriedCallback<Input> {
#callback: (input: Input) => void;
constructor(callback: (input: Input) => void) {
this.#callback = (input: Input) => {
console.log(input);
callback(input);
}
}
call(input: Input) {
this.#callback(input);
}
}
new CurriedCallback((input: string) => {
console.log(input.length);
});
new CurriedCallback((input) => {
console.log(input.length); // Error length does not exist on type unknown
})μ λ€λ¦ ν΄λμ€λ λͺ¨λ νμν λ§€κ°λ³μλ₯Ό μ 곡ν¨μΌλ‘μ¨ μ λ€λ¦ μΈν°νμ΄μ€λ₯Ό ꡬννλ€.
interface ActingCredit<Role> {
role: Role;
};
class MoviePart implements ActingCredit<string> {
role: string;
speaking: boolean;
constructor(role: string, speaking: boolean) {
this.role = role;
this.speaking = speaking;
}
}
class IncorrectExtension implements ActingCredit<string> {
role: boolean;
// Error role in type IncorrectExtension
}ν΄λμ€ λ©μλλ ν΄λμ€ μΈμ€ν΄μ€μ λ³κ°λ‘ μ체 μ λ€λ¦ νμ μ μ μΈ κ°λ₯νλ€. μ λ€λ¦ λ©μλμ λν κ°κ°μ νΈμΆμ κ° νμ λ§€κ°λ³μμ λν΄ λ€λ₯Έ νμ μΈμλ₯Ό κ°λλ€.
class CreatePairFactor<Key> {
key: Key;
constructor(key: Key) {
this.key = key;
}
createPair<Value>(value: Value) {
return { key: this.key, value };
}
};
// νμ
: CreatePairFactor<string>
const factory = new CreatePairFactor("role");
// νμ
: { key: string, value: number }
const numberPair = factory.createPair(10);
// νμ
: { key: string, value: string }
const stringPair = factory.createPair(10);ν΄λμ€μ μ μ λ©€λ²λ μΈμ€ν΄μ€ λ©€λ²μ ꡬλ³λκ³ ν΄λμ€μ νΉμ μΈμ€ν΄μ€μ μ°κ²°λμ΄ μμ§ μλ€. ν΄λμ€μ μ μ λ©€λ²λ ν΄λμ€ μΈμ€ν΄μ€μ μ κ·Όν μ μκ±°λ νμ μ 보λ₯Ό μ§μ ν μ μλ€.
μ μ ν΄λμ€ λ©μλλ νμ λ§€κ°λ³μλ₯Ό μ μΈν μ μμ§λ§ ν΄λμ€μ μ μΈλ μ΄λ€ νμ λ§€κ°λ³μμλ μ κ·Όν μ μλ€.
class BothLogger<OnInstance> {
instanceLog(value: OnInstance) {
console.log(value);
return value;
}
static staticLog<OnStatic>(value: OnStatic) {
let fromInstacne: OnStatic; // Error Static member cannot reference class type aruments
}
}νμ μΈμλ₯Ό μ¬μ©ν΄ μ λ€λ¦μ λ§λλ νμ μ€ν¬λ¦½νΈμ λ§μ§λ§ ꡬ쑰체λ νμ λ³μΉμ΄λ€. κ° νμ λ³μΉμλ T λ₯Ό λ°λ Nullish νμ κ³Ό κ°μ μμμ μμ νμ λ§€κ°λ³μκ° μ£Όμ΄μ§λ€.
type Nullish<T> = T | null | undefined;νμ μ€ν¬λ¦½νΈμ λ΄λ‘μμ μλ¦λ΅κ² κ²°ν©ν΄μ£Όλ νμμ κ°μ₯ μ’μνλ ν¨ν΄μ κΈ°λ₯μ΄λ€.
type Result<Data> = FailureResult | SuccessfulResult<Data>;
interface FailureResult {
error: Error;
succeeded: false;
};
interface SuccessfulResult<Data> {
data: Data;
succeeded: true;
};
function handleresult(result: Result<string>) {
if (result.succeeded) {
console.log(result.data);
} else if (!result.succeeded) {
console.log(result.error)
}
}νμ μ€ν¬λ¦½νΈλ μ λ€λ¦ νμ λ§€κ°λ³μμ λμμ μμ νλ ꡬ문λ μ 곡νλ€.
μ§κΈκΉμ§ μ λ€λ¦ νμ μ΄ νμ μ λν μ΄μ μ μ¬μ©λκ±°λ extends λλ implements μ κΈ°λ³Έ ν΄λμ€λ‘ μ¬μ©λλ κ²½μ° κ° νμ λ§€κ°λ³μμ λν νμ μΈμλ₯Ό μ 곡ν΄μΌ νλ€.
νμ λ§€κ°λ³μ μ μΈ λ€μ = μ κΈ°λ³Έ νμ μ λ°°μΉν΄ νμ μΈμλ₯Ό λͺ μμ μΌλ‘ μ 곡ν μ μλ€. κΈ°λ³Έκ°μ νμ μΈμκ° λͺ μμ μΌλ‘ μ μΈλμ§ μκ³ μ μΆν μ μλ λͺ¨λ νμ νμ μ μ¬μ©λλ€.
interface Quote<T = string> {
value: T;
}
let explicit: Quote<number> = { value: 123 };νμ λ§€κ°λ³μλ λμΌν μ μΈ μμ μμ νμ λ§€κ°λ³μλ₯Ό κΈ°λ³Έκ°μΌλ‘ κ°μ§ μ μλ€. κ° νμ λ§€κ°λ³μλ μ μΈμ λν μλ‘μ΄ νμ μ λμ νλ―λ‘ ν΄λΉ μ μΈ μ΄νμ νμ λ§€κ°λ³μμ λν κΈ°λ³Έκ°μΌλ‘ μ΄λ₯Ό μ¬μ©ν μ μλ€.
λͺ¨λ κΈ°λ³Έ νμ λ§€κ°λ³μλ κΈ°λ³Έ ν¨μ λ§€κ°λ³μμ² λ¨Έ μ μΈ λͺ©λ‘μ μ μΌ λ§μ§λ§μ μμΌ νλ€.
// Error Required type parameters may not follow optional type parameters
function inTheMiddle<First, Second = boolean, Third = number, Fourth>() {}κΈ°λ³Έμ μΌλ‘ μ λ€λ¦ νμ μλ ν΄λμ€ μΈν°νμ΄μ€ μμ―κ° μ λμΈ λ³μΉ λ± λͺ¨λ νμ μ μ 곡ν μ μλ€. κ·Έλ¬λ μΌλΆ ν¨μλ μ νλ νμ μμλ§ μλν΄μΌ νλ€.
νμ μ€ν¬λ¦½νΈλ νμ λ§€κ°λ³μκ° νμ μ νμ₯ν΄μΌ νλ€κ³ μ μΈν μ μμΌλ©° λ³μΉ νμ μλ§ νμ©λλ μμ μ΄λ€. νμ λ§€κ°λ³μλ₯Ό μ ννλ ꡬ문μ λ§€κ°λ³μ μ΄λ¦ λ€μ extends ν€μλλ₯Ό λ°°μΉνκ³ κ·Έ λ€μ μ΄λ₯Ό μ νν νμ μ λ°°μΉνλ€.
μ λ€λ¦ ν¨μκ° T μ λ€λ¦μ λν length λ₯Ό κ°μ§ λͺ¨λ νμ μ λ°μλ€μ΄λλ‘ κ΅¬νν μ½λμ΄λ€. λ¬Έμμ΄ λ°°μ΄ length: number λ₯Ό κ°μ§ κ°μ²΄λ νμ©λμ§λ§ Date μ κ°μ νμ ννμλ μ«μν length λ©€λ²κ° μμΌλ―λ‘ νμ μ€λ₯κ° λ°μνλ€.
interface WithLength {
length: number;
}
function logWithLength<T extends WithLength>(input: T) {
console.log(`Length: ${input.length}`);
return input;
}
logWithLength('string'); // νμ
string
logWithLength([false, true]); // boolean[]
logWithLength({ length: 123 }); // {length: number}
logWithLength(new Date()); // Error Date is not assignable to parameter of type WithLengthextends μ keyof λ₯Ό ν¨κ» μ¬μ©νλ©΄ νμ λ§€κ°λ³μμ ν€λ‘ μ νν μ μλ€. λν μ λ€λ¦ νμ μ ν€λ₯Ό κ±±μ νλ μ μΌν λ°©λ²μ΄κΈ°λ νλ€.
function get<T, Key extends keyof T>(container: T, key: Key) {
return container[key];
}
const role = {
favorite: "a",
others: ["b", "c", "d"],
}
const favorite = get(role, 'favorite'); // νμ
string;
const others = get(role, 'others'); // νμ
string[];
const missing = get(role, 'extras'); // Errorkeyof κ° μμλλΌλ©΄ μ λ€λ¦ key λ§€κ°λ³μλ₯Ό μ¬λ°λ₯΄κ² μ λ ₯ν λ°©λ²μ΄ μμμ κ²μ΄λ€.
Tλ§ μ 곡λκ³ key λ§€κ°λ³μκ° λͺ¨λ keyof T μΌ μ μλ κ²½μ°λΌλ©΄ λ°ν νμ μ Container μ μλ λͺ¨λ μμ± κ°μ λν μ λμΈ νμ μ΄ λλ€.
μ΄λ κ² κ΅¬μ²΄μ μ΄μ§ μμ ν¨μ μ μΈμ κ° νΈμΆμ΄ νμ μΈμλ₯Ό ν΅ν΄ νΉμ key λ₯Ό κ°μ§ μ μμμ νμ μ€ν¬λ¦½νΈμ λνλΌ μ μλ€.
function get<T>(container: T, key: keyof T) {
return container[key];
}
const role = {
favorite: "a",
others: ["b", "c", "d"],
}
const found = get(role, 'favorite'); // νμ
string | string[]νμ μ€ν¬λ¦½νΈλ₯Ό μ²μ μ ν κ°λ°μλ μ΄λ°κΈ μ λ€λ¦μ κ³Όλνκ² μ¬μ©ν΄ μ½κΈ° νΌλμ€λ½κ³ μ§λμΉκ² 볡μ‘ν μ½λλ₯Ό λ§λ€κΈ°λ νλ€.
νμ μ€ν¬λ¦½νΈμ λͺ¨λ² μ¬λ‘λ νμν λλ§ μ λ€λ¦μ μ¬μ©νκ³ μ λ€λ¦μ μ¬μ©ν λλ 무μμ μν΄ μ¬μ©νλμ§ λͺ νν΄μΌ νλ€.
ν¨μμ νμ λ§€κ°λ³μκ° νμνμ§ μ¬λΆλ₯Ό νλ¨ν μ μλ κ°λ¨νκ³ λΉ λ₯Έ λ°©λ²μ νμ λ§€κ°λ³μκ° μ΅μ λ λ² μ΄μ μ¬μ©λμλμ§ νμΈνλ κ²μ΄λ€.
function logIput<Input extends string>(input: Input) {
console.log(`Hi`, input);
}μ΄λ° ν¨μμ Input νμ λ§€κ°λ³μλ₯Ό μ μΈνλ κ²μ λ³λ‘ μΈλͺ¨κ° μλ€.
μ΄νν°λΈ νμ μ€ν¬λ¦½νΈ λ μ λ€λ¦ ν©κΈλ₯ μ μ€λͺ νλ©° μ λ€λ¦μΌλ‘ μμ ν λ μ μ©νκ³ νλ₯ν νλ μκ°νλ€.
νμ μ€ν¬λ¦½νλ₯Ό ν¬ν¨ν λ§μ μΈμ΄κ° μ§ν€κ³ μλ νμ λ§€κ°λ³μμ λν νμ€ λͺ λͺ κ·μΉμ
κΈ°λ³Έμ μΌλ‘ T λ₯Ό μ¬μ©νκ³ νμ νμ λ§€κ°λ³μκ° μ‘΄μ¬νλ©΄ U, V λ±μ μ¬μ©νλ κ²μ΄λ€.