-
1. μΈλ±μ€ μκ·Έλμ²λ?
-
2. μΈλ±μ€ μκ·Έλμ²μ κΈ°λ³Έ λ¬Έλ²
-
3. μΈλ±μ€ μκ·Έλμ²μ λ¨μ
-
3-1. μλͺ»λ ν€λ₯Ό ν¬ν¨ν΄ λͺ¨λ ν€λ₯Ό νμ©νλ€.
-
3-2. νΉμ ν€κ° νμνμ§ μλ€.
-
3-3. ν€λ§λ€ λ€λ₯Έ νμ μ κ°μ§ μ μλ€.
-
3-4. μλ μμ± κΈ°λ₯μ΄ λμνμ§ μλλ€.
-
4. κ·Έλ λ€λ©΄ μΈλ±μ€ μκ·Έλμ²λ μΈμ ?
-
4-1. CSV νμΌμ κ°μ²΄λ‘ λ°κΎΈκΈ°
-
4-2. μ΄(header) μ΄λ¦μ μκ³ μλ κ²½μ°
-
5. μ°κ΄ λ°°μ΄μμμ μΈλ±μ€ μκ·Έλμ²
-
5-1. μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν ν¨μ
-
5-2. Map νμ μ μ¬μ©ν ν¨μ
-
6. νμ μ μ‘°κΈ λ μ’νκΈ°
-
6-1. Record
-
6-2. 맀νλ νμ
1. μΈλ±μ€ μκ·Έλμ²λ?
곡μλ¬Έμμλ μλμ κ°μ΄ μΈλ±μ€ μκ·Έλμ²μ μ¬μ© μμ μ λν΄ μ€λͺ νκ³ μλ€.
Sometimes you donβt know all the names of a typeβs properties ahead of time, but you do know the shape of the values.
In those cases you can use an index signature to describe the types of possible values.
νμ μ μμ±μ λͺ¨λ₯΄μ§λ§ κ°μ ννλ₯Ό μκ³ μμ λ, μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νμ¬ νμ μ μ€λͺ ν μ μλ€.
2. μΈλ±μ€ μκ·Έλμ²μ κΈ°λ³Έ λ¬Έλ²
type Props = { [property: string]: string };
Props
νμ
μ΄ μλ€. μ¬κΈ°μμ μΈλ±μ€ μκ·Έλμ²λ [property: string]: string
μ ν΄λΉνλ€. μ΄λ¬ν μΈλ±μ€ μκ·Έλμ²λ λ€μ μΈ κ°μ§ μλ―Έλ₯Ό λ΄κ³ μλ€.
- ν€μ μ΄λ¦
- μ μμ μμμ
property
μ ν΄λΉ - ν€μ μμΉλ§ νμνλ μ©λ
- 무μν μ μλ μ°Έκ³ μ 보 - λ°λμ
property
κ° μλμ¬λ λλ€. λ€λ₯Έ λ¨μ΄λ μκ΄μλ€.
- μ μμ μμμ
- ν€μ νμ
- μ μμ μμμ 첫 λ²μ§Έ
string
μ ν΄λΉ string
,number
,symbol
μ€ νλ- 보ν΅μ
string
μ μ¬μ©
- μ μμ μμμ 첫 λ²μ§Έ
- κ°μ νμ
- μ μμ μμμ μΈλ²μ§Έ
string
μ ν΄λΉ - λͺ¨λ νμ μ΄ κ°λ₯
- μ μμ μμμ μΈλ²μ§Έ
3. μΈλ±μ€ μκ·Έλμ²μ λ¨μ
λ€μ μμ λ₯Ό ν΅ν΄ μΈλ±μ€ μκ·Έλμ²μ λ¨μ μ λν΄ μ΄ν΄λ³΄μ.
type Person = { [key: string]: string };
const person: Person = {
name: 'noah',
address: 'somewhere',
age: '30',
};
3-1. μλͺ»λ ν€λ₯Ό ν¬ν¨ν΄ λͺ¨λ ν€λ₯Ό νμ©νλ€.
key
λ string
μ΄κΈ°λ§ νλ©΄ μ΄λ ν κ°λ μ¬ μ μλ€. λλ¬Έμ name
μ΄ μλλΌ Name
μΌλ‘ ν€μ μ΄λ¦μ μ νμ¬λ μ€λ₯κ° λμ§ μλλ€.
const person: Person = {
Name: 'noah',
address: 'somewhere',
age: '30',
};
3-2. νΉμ ν€κ° νμνμ§ μλ€.
person
κ°μ²΄μ λ°λμ μ‘΄μ¬ν΄μΌ ν μμ±(ν€-κ°)μ μ ν μ μλ€. λλ¬Έμ {}
λ νμ©νλ€.
const person: Person = {};
3-3. ν€λ§λ€ λ€λ₯Έ νμ μ κ°μ§ μ μλ€.
μμ μμμμ age
λ string
μ΄ μλλΌ number
κ° λ μ ν©νλ€.
νμ§λ§ age
λ₯Ό number
λ‘ νλ©΄ νμ
μ€ν¬λ¦½νΈλ μ€λ₯λ₯Ό λνλΈλ€.
3-4. μλ μμ± κΈ°λ₯μ΄ λμνμ§ μλλ€.
μ΄λ ν μμ±μ΄ μλμ§ μ μ μκΈ° λλ¬Έμ κ°μ²΄λ₯Ό λ§λ€ λ, μλμμ± κΈ°λ₯μ μ¬μ©ν μ μλ€.
λν, κ°μ²΄λ₯Ό λ§λ€μλλΌλ κ°μ²΄μ μμ±μ μ κ·Όνλ κ³Όμ μμλ μλμμ± κΈ°λ₯μ μ¬μ©ν μ μλ€.
λ€μμ νμ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μ»μ μ μλ μλμμ± κΈ°λ₯μ μμλ€. μ¦, μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νλ©΄ μλμ κ°μ κΈ°λ₯μ μ¬μ©ν μ μλ€.


4. κ·Έλ λ€λ©΄ μΈλ±μ€ μκ·Έλμ²λ μΈμ ?
κ°λ₯νλ€λ©΄ μΈλ±μ€ μκ·Έλμ²λ³΄λ€ μ νν νμ μ μ¬μ©νλ κ²μ΄ μ’λ€. νμ§λ§ νΉλ³ν κ²½μ°μ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν΄μΌ νλ€. λ°λ‘ λ°νμ λκΉμ§ κ°μ²΄μ μμ±μ μ μ μμ κ²½μ°μ΄λ€.
μ νν μμ±μ μ΄λ¦μ μμ§ λͺ»νκΈ° λλ¬Έμ 미리 νμ μΌλ‘ μ ν μ μκΈ° λλ¬Έμ΄λ€.
4-1. CSV νμΌμ κ°μ²΄λ‘ λ°κΎΈκΈ°
μλμ νλ₯Ό 보μ.
μ°λ | μ μ‘°μ¬ | λͺ¨λΈ | μ€λͺ | κ°κ²© |
---|---|---|---|---|
1997 | Ford | E350 | ac abs moon | 3000.00 |
1999 | Chevy | Venture Extended Edition | 4900.00 | |
1999 | Chevy | Venture Extended Edition | Very Large | 5000.00 |
1996 | Jeep | Grand Cherokee | MUST SELL! air moon roof loaded | 4799.00 |
첫 λ²μ§Έ μ΄μ headerμ΄λ©° μ΄λ μ΄λ€ λ°μ΄ν°λ₯Ό κ°μ Έμ ννν κ²μΈμ§μ λ°λΌ λ¬λΌμ§ μ μλ€. μ¦, headerμ λ΄μ©μ΄ λ λ§μμ§ μλ, μ μ΄μ§ μλ νΉμ λ€λ₯Έ μ΄λ¦μΌλ‘ λ°λ μ μλ€. μ΄λ° κ²½μ° μ°λ¦° headerκ° λ¬΄μμΈμ§ νμ μ§μ μ μλ λ¬Έμ κ° μκΈ΄λ€. μ΄λ° λ°μ΄ν°λ₯Ό λμ λ°μ΄ν°
λΌκ³ νλ©° λμ λ°μ΄ν°
λ₯Ό λ€λ£¨λ κ²½μ° μΈλ±μ€ μκ·Έλμ²λ₯Ό ν΅ν΄ νμ
μ μ ν μ μλ€.
μμ κ°μ νλ₯Ό CSV νμΌ νμμΌλ‘ λ°κΎΈλ©΄ μλμ κ°λ€.
CSV(μμ΄: comma-separated values)λ λͺ κ°μ§ νλλ₯Ό μΌν(,)λ‘ κ΅¬λΆν ν μ€νΈ λ°μ΄ν° λ° ν μ€νΈ νμΌμ΄λ€
const exampleCSV = `μ°λ,μ μ‘°μ¬,λͺ¨λΈ,μ€λͺ
,κ°κ²©
1997,Ford,E350,ac abs moon,3000.00
1999,Chevy,Venture Extended Edition,,4900.00
1999,Chevy,Venture Extended Edition,Very Large,5000.00
1996,Jeep,Grand Cherokee,MUST SELL! air moon roof loaded,4799.00`;
κ° μ΄μ κ°μ headerμ μ΄λ¦κ³Ό 맀ννλ κ°μ²΄λ‘ λνλ΄μ΄ 보μ.
function parseCSV(input: string): { [columnName: string]: string }[] {
const lines = input.split('\n'); // κ° μ΄μ λλλ€.
const [header, ...rows] = lines; // 첫λ²μ§Έ μ΄μ header, λλ¨Έμ§λ rowsλ‘ λλλ€.
const headerColumns = header.split(','); // headerμ λ΄μ©μ ,λ₯Ό κΈ°μ€μΌλ‘ λλλ€.
// μ κ³Όμ μ ν΅ν΄ λμ¨ κ°λ€μ΄ μ νν μ΄λ€ κ°μΈμ§ λ°νμ μ΄μ μ λͺ¨λ₯΄κΈ° λλ¬Έμ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νλ€.
return rows.map((rowStr) => {
const row: { [columnName: string]: string } = {}; // λ¦¬ν΄ ν κ°
rowStr.split(',').forEach((cell, i) => {
row[headerColumns[i]] = cell; // κ° νμ λ§λ headerμ μ΄λ¦μ 맀ν½νμ¬ rowμ μΆκ°νλ€.
});
return row; // λ°ν
});
}
λ€μμ κ²°κ³Όκ°μ΄λ€.
parseCSV(exampleCSV);
[
{
μ°λ: '1997',
μ μ‘°μ¬: 'Ford',
λͺ¨λΈ: 'E350',
μ€λͺ
: 'ac abs moon',
κ°κ²©: '3000.00',
},
{
μ°λ: '1999',
μ μ‘°μ¬: 'Chevy',
λͺ¨λΈ: 'Venture Extended Edition',
μ€λͺ
: '',
κ°κ²©: '4900.00',
},
{
μ°λ: '1999',
μ μ‘°μ¬: 'Chevy',
λͺ¨λΈ: 'Venture Extended Edition',
μ€λͺ
: 'Very Large',
κ°κ²©: '5000.00',
},
{
μ°λ: '1996',
μ μ‘°μ¬: 'Jeep',
λͺ¨λΈ: 'Grand Cherokee',
μ€λͺ
: 'MUST SELL! air moon roof loaded',
κ°κ²©: '4799.00',
},
];
4-2. μ΄(header) μ΄λ¦μ μκ³ μλ κ²½μ°
νμ§λ§ μ΄ μ΄λ¦μ μκ³ μλ νΉμ ν μν©μ΄λΌλ©΄ 미리 μ μΈν΄ λ νμ μΌλ‘ λ¨μΈλ¬Έμ μ¬μ©νλ κ²μ΄ μ’λ€.
type Product = {
μ°λ: string;
μ μ‘°μ¬: string;
λͺ¨λΈ: string;
μ€λͺ
: string;
κ°κ²©: string;
};
const products = parseCSV(exampleCSV) as unknown as Product;
5. μ°κ΄ λ°°μ΄μμμ μΈλ±μ€ μκ·Έλμ²
μ°κ΄ λ°°μ΄μ΄λ? ν€ νλμ κ° νλκ° μ°κ΄λμ΄ μμΌλ©° ν€λ₯Ό ν΅ν΄ μ°κ΄λλ κ°μ μ»μ μ μλ μλ£κ΅¬μ΄λ€.
μλ₯Ό λ€μ΄ λ¬Έμμ΄ λ΄μμ λ¨μ΄λ₯Ό κΈ°μ€μΌλ‘ μͺΌκ°μ΄, λ¨μ΄κ° λͺ λ² λ±μ₯νλμ§λ₯Ό κ°μ²΄λ‘ νννκ³ μ νλ€. μ΄λ, ν€λ λ¨μ΄κ° λ κ²μ΄κ³ κ°μ λ¨μ΄κ° λ¬Έμμ΄μμ λ±μ₯ν μκ° λλ€.
"Objects have a constructor"μ΄λΌλ λ¬Έμμ΄μ λ°νμΌλ‘ κ°μ²΄λ₯Ό λ§λλ©΄ μμλλ κ°μ²΄λ λ€μκ³Ό κ°λ€.
{
Objects: 1;
have: 1;
a: 1;
constructor: 1;
}
μ΄μ κ°μ κ°μ²΄λ₯Ό μμ±νλ ν¨μλ₯Ό μΈλ±μ€ μκ·Έλμ²(5-1) λλ Map νμ (5-2)μ μ΄μ©νμ¬ λ§λ€μ΄λ³΄μ.
5-1. μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν ν¨μ
function countWords(text: string) {
const counts: { [word: string]: number } = {};
const words = text.split(/[\s,.]+/);
words.forEach((word) => {
counts[word] = ([word] || 0) + 1;
});
return counts;
}
μ ν¨μλ₯Ό ν΅ν΄ κ²°κ³Όλ₯Ό μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
{
Objects: 1,
have: 1,
a: 1,
constructor: 'function Object() { [native code] }1'
}
constructor
λΆλΆμ΄ μ΄μνλ€. μ΄λ constructor
μ μ΄κΈ°κ°μ΄ undefined
κ° μλλΌ Object.prototype
μ μλ μμ±μ ν¨μμ΄κΈ° λλ¬Έμ΄λ€.
5-2. Map νμ μ μ¬μ©ν ν¨μ
function countWords(text: string) {
const counts: Map<string, number> = new Map(); // Map νμ
μ μ¬μ©
const words = text.split(/[\s,.]+/);
words.forEach((word) => {
counts.set(word, (counts.get(word) || 0) + 1);
});
return counts;
}
Map(4) { 'Objects' => 1, 'have' => 1, 'a' => 1, 'constructor' => 1 }
μνλ κ²°κ³Όλ₯Ό λ³Ό μ μλ€.
6. νμ μ μ‘°κΈ λ μ’νκΈ°
λ€μμ μν©μ κ°μ ν΄ λ³΄μ.
- λ°μ΄ν°μ a, b, c, d, eμ ν€κ° μλ€.
- a, b, c, d, eλ λͺ¨λ νμκ° μλλ€.
- λ°μ΄ν°μ μ νν μΌλ§λ§νΌ ν€κ° λ€μ΄μλμ§ λͺ¨λ₯Έλ€.
μμ κ°μ μν©μμ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν μ μλ€.
type Row = { [key: string]: string };
νμ§λ§ key
κ° string
μ΄λΌλ κ²μ λ무 κ΄λ²μνλ€. λλ¬Έμ κ΄λ²μν λ²μλ₯Ό μ’νλ κ²μ΄ μ’λ€.
μ΄λ₯Ό μν λ°©λ²μ μμ보μ.
6-1. Record
Record
λ λ€μκ³Ό κ°μ ννλ₯Ό κ°μ§κ³ μλ€.
// lib.es5.d.ts μμμ μ μ
type Record<K extends keyof any, T> = {
[P in K]: T;
};
type Record<K extends string | number | symbol, T> = { [P in K]: T; }
λ¨Όμ ,
λ₯Ό κΈ°μ€μΌλ‘ μΌμͺ½μ΄ key
, μ€λ₯Έμͺ½μ΄ value
μ΄λ€. κ·Έλ¦¬κ³ K
μ κ°μ string
, number
, symbol
μ€ νλμΌ μλ μκ³ λΆλΆ μ§ν©μΌ μλ μλ€.
μ΄λ¬ν Record
λ₯Ό μ¬μ©νμ¬ μΈλ±μ€ μκ·Έλμ²λ₯Ό ꡬννλ©΄ μλμ κ°λ€.
type Row = Record<string, string>;
λ§€μ° κ°λ¨νλ€. νμ§λ§ μμ§ μμ¬μ΄ μ μ λ¨μμλ€. ν€μ κ°μ΄ string
μ΄κΈ° λλ¬Έμ μμ§ κ΄λ²μνλ€. μ΄λ₯Ό 쑰건μ λ§κ² λ°κΎΈμ΄ 보μ.
쑰건μ a, b, c, d, e ν€κ° μλ€κ³ νμμΌλ string
λμ μ λμ¨μΌλ‘ ννν΄ λ³΄μ.
type Row = Record<'a' | 'b' | 'c' | 'd' | 'e', string>;
// type Row1 = {
// a: string;
// b: string;
// c: string;
// d: string;
// e: string;
// };
'a' | 'b' | 'c' | 'd' | 'e'
λ string
μ λΆλΆ μ§ν©μ΄λ―λ‘ κ°λ₯νλ€.
νμ§λ§ μμ§ μμ¬μ΄ μ μ΄ μλ€. μμ§ λͺ¨λ ν€λ€μ΄ νμκ°μ΄λΌλ κ²μ΄λ€. 쑰건μ 보μλ©΄ λͺ¨λ νμκ°μ΄ μλλ€. μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μ μμ Partial
λ₯Ό λΆμ΄λ©΄ λλ€.
type Row = Partial<Record<'a' | 'b' | 'c' | 'd' | 'e', string>>;
// type Row = {
// a?: string | undefined;
// b?: string | undefined;
// c?: string | undefined;
// d?: string | undefined;
// e?: string | undefined;
// }
μ΄λ‘μ¨ string
μ΄λΌλ κ΄λ²μν λ²μλ₯Ό μ’νλ©΄μ 쑰건μ νμ
μ λ§μ‘±ν μ μλ€.
string
μ΄λΌλ κ΄λ²μν λ²μλ₯Ό μ λμ¨μ μ¬μ©νμ¬ λ²μλ₯Ό μ’νλ©΄ λ μ΄μ μΈλ±μ€ μκ·Έλμ²λΌκ³ λΆλ₯Ό μ μλ κ² μλκΉ?
6-2. 맀νλ νμ
λ¨Όμ λ€μμ 맀νλ νμ μ μ¬μ©ν μΈλ±μ€ μκ·Έλμ²μ΄λ€.
type Row = { [k in string]: string };
μ¬μ€ 맀νλ νμ
μ μ’ λ μ½κ² μ¬μ©νλ λ°©λ²μ΄ Record
μ΄λ€. νμ§λ§ 맀νλ νμ
μ μ¬μ©νλ©΄ λ μ μ°νκ² νμ
μ μ ν μ μλ€.
μλ₯Ό λ€μ΄ μμ a, b, c, d, eμ ν€ μ€ d
λ string
μ΄ μλλΌ number
λΌκ³ κ°μ ν΄ λ³΄μ. μ΄λ λ€μκ³Ό κ°μ΄ μ½λλ₯Ό μμ±νλ©΄ λλ€.
type Row = {
[k in 'a' | 'b' | 'c' | 'd' | 'e']: k extends 'd' ? number : string;
};
'π₯ νμ μ€ν¬λ¦½νΈ > Effective Typescript' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
1. μΈλ±μ€ μκ·Έλμ²λ?
곡μλ¬Έμμλ μλμ κ°μ΄ μΈλ±μ€ μκ·Έλμ²μ μ¬μ© μμ μ λν΄ μ€λͺ νκ³ μλ€.
Sometimes you donβt know all the names of a typeβs properties ahead of time, but you do know the shape of the values.
In those cases you can use an index signature to describe the types of possible values.
νμ μ μμ±μ λͺ¨λ₯΄μ§λ§ κ°μ ννλ₯Ό μκ³ μμ λ, μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νμ¬ νμ μ μ€λͺ ν μ μλ€.
2. μΈλ±μ€ μκ·Έλμ²μ κΈ°λ³Έ λ¬Έλ²
type Props = { [property: string]: string };
Props
νμ
μ΄ μλ€. μ¬κΈ°μμ μΈλ±μ€ μκ·Έλμ²λ [property: string]: string
μ ν΄λΉνλ€. μ΄λ¬ν μΈλ±μ€ μκ·Έλμ²λ λ€μ μΈ κ°μ§ μλ―Έλ₯Ό λ΄κ³ μλ€.
- ν€μ μ΄λ¦
- μ μμ μμμ
property
μ ν΄λΉ - ν€μ μμΉλ§ νμνλ μ©λ
- 무μν μ μλ μ°Έκ³ μ 보 - λ°λμ
property
κ° μλμ¬λ λλ€. λ€λ₯Έ λ¨μ΄λ μκ΄μλ€.
- μ μμ μμμ
- ν€μ νμ
- μ μμ μμμ 첫 λ²μ§Έ
string
μ ν΄λΉ string
,number
,symbol
μ€ νλ- 보ν΅μ
string
μ μ¬μ©
- μ μμ μμμ 첫 λ²μ§Έ
- κ°μ νμ
- μ μμ μμμ μΈλ²μ§Έ
string
μ ν΄λΉ - λͺ¨λ νμ μ΄ κ°λ₯
- μ μμ μμμ μΈλ²μ§Έ
3. μΈλ±μ€ μκ·Έλμ²μ λ¨μ
λ€μ μμ λ₯Ό ν΅ν΄ μΈλ±μ€ μκ·Έλμ²μ λ¨μ μ λν΄ μ΄ν΄λ³΄μ.
type Person = { [key: string]: string };
const person: Person = {
name: 'noah',
address: 'somewhere',
age: '30',
};
3-1. μλͺ»λ ν€λ₯Ό ν¬ν¨ν΄ λͺ¨λ ν€λ₯Ό νμ©νλ€.
key
λ string
μ΄κΈ°λ§ νλ©΄ μ΄λ ν κ°λ μ¬ μ μλ€. λλ¬Έμ name
μ΄ μλλΌ Name
μΌλ‘ ν€μ μ΄λ¦μ μ νμ¬λ μ€λ₯κ° λμ§ μλλ€.
const person: Person = {
Name: 'noah',
address: 'somewhere',
age: '30',
};
3-2. νΉμ ν€κ° νμνμ§ μλ€.
person
κ°μ²΄μ λ°λμ μ‘΄μ¬ν΄μΌ ν μμ±(ν€-κ°)μ μ ν μ μλ€. λλ¬Έμ {}
λ νμ©νλ€.
const person: Person = {};
3-3. ν€λ§λ€ λ€λ₯Έ νμ μ κ°μ§ μ μλ€.
μμ μμμμ age
λ string
μ΄ μλλΌ number
κ° λ μ ν©νλ€.
νμ§λ§ age
λ₯Ό number
λ‘ νλ©΄ νμ
μ€ν¬λ¦½νΈλ μ€λ₯λ₯Ό λνλΈλ€.
3-4. μλ μμ± κΈ°λ₯μ΄ λμνμ§ μλλ€.
μ΄λ ν μμ±μ΄ μλμ§ μ μ μκΈ° λλ¬Έμ κ°μ²΄λ₯Ό λ§λ€ λ, μλμμ± κΈ°λ₯μ μ¬μ©ν μ μλ€.
λν, κ°μ²΄λ₯Ό λ§λ€μλλΌλ κ°μ²΄μ μμ±μ μ κ·Όνλ κ³Όμ μμλ μλμμ± κΈ°λ₯μ μ¬μ©ν μ μλ€.
λ€μμ νμ μ€ν¬λ¦½νΈλ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μ»μ μ μλ μλμμ± κΈ°λ₯μ μμλ€. μ¦, μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νλ©΄ μλμ κ°μ κΈ°λ₯μ μ¬μ©ν μ μλ€.


4. κ·Έλ λ€λ©΄ μΈλ±μ€ μκ·Έλμ²λ μΈμ ?
κ°λ₯νλ€λ©΄ μΈλ±μ€ μκ·Έλμ²λ³΄λ€ μ νν νμ μ μ¬μ©νλ κ²μ΄ μ’λ€. νμ§λ§ νΉλ³ν κ²½μ°μ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν΄μΌ νλ€. λ°λ‘ λ°νμ λκΉμ§ κ°μ²΄μ μμ±μ μ μ μμ κ²½μ°μ΄λ€.
μ νν μμ±μ μ΄λ¦μ μμ§ λͺ»νκΈ° λλ¬Έμ 미리 νμ μΌλ‘ μ ν μ μκΈ° λλ¬Έμ΄λ€.
4-1. CSV νμΌμ κ°μ²΄λ‘ λ°κΎΈκΈ°
μλμ νλ₯Ό 보μ.
μ°λ | μ μ‘°μ¬ | λͺ¨λΈ | μ€λͺ | κ°κ²© |
---|---|---|---|---|
1997 | Ford | E350 | ac abs moon | 3000.00 |
1999 | Chevy | Venture Extended Edition | 4900.00 | |
1999 | Chevy | Venture Extended Edition | Very Large | 5000.00 |
1996 | Jeep | Grand Cherokee | MUST SELL! air moon roof loaded | 4799.00 |
첫 λ²μ§Έ μ΄μ headerμ΄λ©° μ΄λ μ΄λ€ λ°μ΄ν°λ₯Ό κ°μ Έμ ννν κ²μΈμ§μ λ°λΌ λ¬λΌμ§ μ μλ€. μ¦, headerμ λ΄μ©μ΄ λ λ§μμ§ μλ, μ μ΄μ§ μλ νΉμ λ€λ₯Έ μ΄λ¦μΌλ‘ λ°λ μ μλ€. μ΄λ° κ²½μ° μ°λ¦° headerκ° λ¬΄μμΈμ§ νμ μ§μ μ μλ λ¬Έμ κ° μκΈ΄λ€. μ΄λ° λ°μ΄ν°λ₯Ό λμ λ°μ΄ν°
λΌκ³ νλ©° λμ λ°μ΄ν°
λ₯Ό λ€λ£¨λ κ²½μ° μΈλ±μ€ μκ·Έλμ²λ₯Ό ν΅ν΄ νμ
μ μ ν μ μλ€.
μμ κ°μ νλ₯Ό CSV νμΌ νμμΌλ‘ λ°κΎΈλ©΄ μλμ κ°λ€.
CSV(μμ΄: comma-separated values)λ λͺ κ°μ§ νλλ₯Ό μΌν(,)λ‘ κ΅¬λΆν ν μ€νΈ λ°μ΄ν° λ° ν μ€νΈ νμΌμ΄λ€
const exampleCSV = `μ°λ,μ μ‘°μ¬,λͺ¨λΈ,μ€λͺ
,κ°κ²©
1997,Ford,E350,ac abs moon,3000.00
1999,Chevy,Venture Extended Edition,,4900.00
1999,Chevy,Venture Extended Edition,Very Large,5000.00
1996,Jeep,Grand Cherokee,MUST SELL! air moon roof loaded,4799.00`;
κ° μ΄μ κ°μ headerμ μ΄λ¦κ³Ό 맀ννλ κ°μ²΄λ‘ λνλ΄μ΄ 보μ.
function parseCSV(input: string): { [columnName: string]: string }[] {
const lines = input.split('\n'); // κ° μ΄μ λλλ€.
const [header, ...rows] = lines; // 첫λ²μ§Έ μ΄μ header, λλ¨Έμ§λ rowsλ‘ λλλ€.
const headerColumns = header.split(','); // headerμ λ΄μ©μ ,λ₯Ό κΈ°μ€μΌλ‘ λλλ€.
// μ κ³Όμ μ ν΅ν΄ λμ¨ κ°λ€μ΄ μ νν μ΄λ€ κ°μΈμ§ λ°νμ μ΄μ μ λͺ¨λ₯΄κΈ° λλ¬Έμ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©νλ€.
return rows.map((rowStr) => {
const row: { [columnName: string]: string } = {}; // λ¦¬ν΄ ν κ°
rowStr.split(',').forEach((cell, i) => {
row[headerColumns[i]] = cell; // κ° νμ λ§λ headerμ μ΄λ¦μ 맀ν½νμ¬ rowμ μΆκ°νλ€.
});
return row; // λ°ν
});
}
λ€μμ κ²°κ³Όκ°μ΄λ€.
parseCSV(exampleCSV);
[
{
μ°λ: '1997',
μ μ‘°μ¬: 'Ford',
λͺ¨λΈ: 'E350',
μ€λͺ
: 'ac abs moon',
κ°κ²©: '3000.00',
},
{
μ°λ: '1999',
μ μ‘°μ¬: 'Chevy',
λͺ¨λΈ: 'Venture Extended Edition',
μ€λͺ
: '',
κ°κ²©: '4900.00',
},
{
μ°λ: '1999',
μ μ‘°μ¬: 'Chevy',
λͺ¨λΈ: 'Venture Extended Edition',
μ€λͺ
: 'Very Large',
κ°κ²©: '5000.00',
},
{
μ°λ: '1996',
μ μ‘°μ¬: 'Jeep',
λͺ¨λΈ: 'Grand Cherokee',
μ€λͺ
: 'MUST SELL! air moon roof loaded',
κ°κ²©: '4799.00',
},
];
4-2. μ΄(header) μ΄λ¦μ μκ³ μλ κ²½μ°
νμ§λ§ μ΄ μ΄λ¦μ μκ³ μλ νΉμ ν μν©μ΄λΌλ©΄ 미리 μ μΈν΄ λ νμ μΌλ‘ λ¨μΈλ¬Έμ μ¬μ©νλ κ²μ΄ μ’λ€.
type Product = {
μ°λ: string;
μ μ‘°μ¬: string;
λͺ¨λΈ: string;
μ€λͺ
: string;
κ°κ²©: string;
};
const products = parseCSV(exampleCSV) as unknown as Product;
5. μ°κ΄ λ°°μ΄μμμ μΈλ±μ€ μκ·Έλμ²
μ°κ΄ λ°°μ΄μ΄λ? ν€ νλμ κ° νλκ° μ°κ΄λμ΄ μμΌλ©° ν€λ₯Ό ν΅ν΄ μ°κ΄λλ κ°μ μ»μ μ μλ μλ£κ΅¬μ΄λ€.
μλ₯Ό λ€μ΄ λ¬Έμμ΄ λ΄μμ λ¨μ΄λ₯Ό κΈ°μ€μΌλ‘ μͺΌκ°μ΄, λ¨μ΄κ° λͺ λ² λ±μ₯νλμ§λ₯Ό κ°μ²΄λ‘ νννκ³ μ νλ€. μ΄λ, ν€λ λ¨μ΄κ° λ κ²μ΄κ³ κ°μ λ¨μ΄κ° λ¬Έμμ΄μμ λ±μ₯ν μκ° λλ€.
"Objects have a constructor"μ΄λΌλ λ¬Έμμ΄μ λ°νμΌλ‘ κ°μ²΄λ₯Ό λ§λλ©΄ μμλλ κ°μ²΄λ λ€μκ³Ό κ°λ€.
{
Objects: 1;
have: 1;
a: 1;
constructor: 1;
}
μ΄μ κ°μ κ°μ²΄λ₯Ό μμ±νλ ν¨μλ₯Ό μΈλ±μ€ μκ·Έλμ²(5-1) λλ Map νμ (5-2)μ μ΄μ©νμ¬ λ§λ€μ΄λ³΄μ.
5-1. μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν ν¨μ
function countWords(text: string) {
const counts: { [word: string]: number } = {};
const words = text.split(/[\s,.]+/);
words.forEach((word) => {
counts[word] = ([word] || 0) + 1;
});
return counts;
}
μ ν¨μλ₯Ό ν΅ν΄ κ²°κ³Όλ₯Ό μ΄ν΄λ³΄λ©΄ λ€μκ³Ό κ°λ€.
{
Objects: 1,
have: 1,
a: 1,
constructor: 'function Object() { [native code] }1'
}
constructor
λΆλΆμ΄ μ΄μνλ€. μ΄λ constructor
μ μ΄κΈ°κ°μ΄ undefined
κ° μλλΌ Object.prototype
μ μλ μμ±μ ν¨μμ΄κΈ° λλ¬Έμ΄λ€.
5-2. Map νμ μ μ¬μ©ν ν¨μ
function countWords(text: string) {
const counts: Map<string, number> = new Map(); // Map νμ
μ μ¬μ©
const words = text.split(/[\s,.]+/);
words.forEach((word) => {
counts.set(word, (counts.get(word) || 0) + 1);
});
return counts;
}
Map(4) { 'Objects' => 1, 'have' => 1, 'a' => 1, 'constructor' => 1 }
μνλ κ²°κ³Όλ₯Ό λ³Ό μ μλ€.
6. νμ μ μ‘°κΈ λ μ’νκΈ°
λ€μμ μν©μ κ°μ ν΄ λ³΄μ.
- λ°μ΄ν°μ a, b, c, d, eμ ν€κ° μλ€.
- a, b, c, d, eλ λͺ¨λ νμκ° μλλ€.
- λ°μ΄ν°μ μ νν μΌλ§λ§νΌ ν€κ° λ€μ΄μλμ§ λͺ¨λ₯Έλ€.
μμ κ°μ μν©μμ μΈλ±μ€ μκ·Έλμ²λ₯Ό μ¬μ©ν μ μλ€.
type Row = { [key: string]: string };
νμ§λ§ key
κ° string
μ΄λΌλ κ²μ λ무 κ΄λ²μνλ€. λλ¬Έμ κ΄λ²μν λ²μλ₯Ό μ’νλ κ²μ΄ μ’λ€.
μ΄λ₯Ό μν λ°©λ²μ μμ보μ.
6-1. Record
Record
λ λ€μκ³Ό κ°μ ννλ₯Ό κ°μ§κ³ μλ€.
// lib.es5.d.ts μμμ μ μ
type Record<K extends keyof any, T> = {
[P in K]: T;
};
type Record<K extends string | number | symbol, T> = { [P in K]: T; }
λ¨Όμ ,
λ₯Ό κΈ°μ€μΌλ‘ μΌμͺ½μ΄ key
, μ€λ₯Έμͺ½μ΄ value
μ΄λ€. κ·Έλ¦¬κ³ K
μ κ°μ string
, number
, symbol
μ€ νλμΌ μλ μκ³ λΆλΆ μ§ν©μΌ μλ μλ€.
μ΄λ¬ν Record
λ₯Ό μ¬μ©νμ¬ μΈλ±μ€ μκ·Έλμ²λ₯Ό ꡬννλ©΄ μλμ κ°λ€.
type Row = Record<string, string>;
λ§€μ° κ°λ¨νλ€. νμ§λ§ μμ§ μμ¬μ΄ μ μ λ¨μμλ€. ν€μ κ°μ΄ string
μ΄κΈ° λλ¬Έμ μμ§ κ΄λ²μνλ€. μ΄λ₯Ό 쑰건μ λ§κ² λ°κΎΈμ΄ 보μ.
쑰건μ a, b, c, d, e ν€κ° μλ€κ³ νμμΌλ string
λμ μ λμ¨μΌλ‘ ννν΄ λ³΄μ.
type Row = Record<'a' | 'b' | 'c' | 'd' | 'e', string>;
// type Row1 = {
// a: string;
// b: string;
// c: string;
// d: string;
// e: string;
// };
'a' | 'b' | 'c' | 'd' | 'e'
λ string
μ λΆλΆ μ§ν©μ΄λ―λ‘ κ°λ₯νλ€.
νμ§λ§ μμ§ μμ¬μ΄ μ μ΄ μλ€. μμ§ λͺ¨λ ν€λ€μ΄ νμκ°μ΄λΌλ κ²μ΄λ€. 쑰건μ 보μλ©΄ λͺ¨λ νμκ°μ΄ μλλ€. μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μ μμ Partial
λ₯Ό λΆμ΄λ©΄ λλ€.
type Row = Partial<Record<'a' | 'b' | 'c' | 'd' | 'e', string>>;
// type Row = {
// a?: string | undefined;
// b?: string | undefined;
// c?: string | undefined;
// d?: string | undefined;
// e?: string | undefined;
// }
μ΄λ‘μ¨ string
μ΄λΌλ κ΄λ²μν λ²μλ₯Ό μ’νλ©΄μ 쑰건μ νμ
μ λ§μ‘±ν μ μλ€.
string
μ΄λΌλ κ΄λ²μν λ²μλ₯Ό μ λμ¨μ μ¬μ©νμ¬ λ²μλ₯Ό μ’νλ©΄ λ μ΄μ μΈλ±μ€ μκ·Έλμ²λΌκ³ λΆλ₯Ό μ μλ κ² μλκΉ?
6-2. 맀νλ νμ
λ¨Όμ λ€μμ 맀νλ νμ μ μ¬μ©ν μΈλ±μ€ μκ·Έλμ²μ΄λ€.
type Row = { [k in string]: string };
μ¬μ€ 맀νλ νμ
μ μ’ λ μ½κ² μ¬μ©νλ λ°©λ²μ΄ Record
μ΄λ€. νμ§λ§ 맀νλ νμ
μ μ¬μ©νλ©΄ λ μ μ°νκ² νμ
μ μ ν μ μλ€.
μλ₯Ό λ€μ΄ μμ a, b, c, d, eμ ν€ μ€ d
λ string
μ΄ μλλΌ number
λΌκ³ κ°μ ν΄ λ³΄μ. μ΄λ λ€μκ³Ό κ°μ΄ μ½λλ₯Ό μμ±νλ©΄ λλ€.
type Row = {
[k in 'a' | 'b' | 'c' | 'd' | 'e']: k extends 'd' ? number : string;
};