ํ์ ์คํฌ๋ฆฝํธ๋ ์ ์ ํ์ ์ธ์ด์ด๋ฉฐ ์๋ฐ์คํฌ๋ฆฝํธ์ ํ์ ์์คํ ์ ์ ์ฉํด ์์ ์ฑ์ ๋ณด์ฅํ๋ค.
ํ์ ์์คํ ์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ค.
- ์๋ฌ๋ฅผ catch ํ๋ ๊ฒ์ ๋์์ค๋ค.
- Type annotation์ ํตํด ํ๋กํผํฐ๋ค์ ๋ํ ๋ฌ์ฌ์ ์ฝ๋ฉํธ ์ ๊ณต
- ์ฝ๋ ์์ฑ์์๋ง active
Process
- TypeScript code โ TypeScript complierโ Plain old JavaScript
- ๋ธ๋ผ์ฐ์ ์์๋ ํ์ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์คํํ๋ค.
ํ์ ์ด๋ ํ๋กํผํฐ์ ๊ฐ๋ค์ ๊ฐ์ง๊ณ ์๋ ํจ์๋ฅผ ๋ํ๋ด๊ธฐ ์ํ ๋ฐฉ์์ด๋ค.
์์ ํ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
number
,boolean
,void
,undefined
,string
,symbol
,null
๊ฐ์ฒด ํ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
functions
,arrays
,classes
,objects
๊ทธ๋ ๋ค๋ฉด ์ ํ์ ์ ์ ๊ฒฝ์จ์ผํ ๊น?
Why do we care about types?
๊ทธ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
-
ํ์ ๋ค์ ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ๊ฐ ์๋ฌ๋ฅผ ์ํด ์ฐ๋ฆฌ๊ฐ ์์ฑํ ์ฝ๋๋ฅผ ๋ถ์ํ ๋ ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ด๋ค.
-
ํ์ ์ ๋ค๋ฅธ ์ฌ๋์ด ์์ฑํ ์ฝ๋์ ์ดํด๋ฅผ ๋์ธ ์ ์๋ค.
ํ์ ์คํฌ๋ฆฝํธ์์์ ํ์ ์ ์ฌ์ฉ๋ ์ ์๋ ์ฝ๋ ๋ชจ๋ ๊ณณ์์ ์ฌ์ฉ๋์ด์ผํ๋ค.
Typescript tries to figure out what type of value a variable refers to
type infrenece๋ ํ์ ์คํฌ๋ฆฝํธ๊ฐ ์๋์ผ๋ก ํ์ ์ ์ถ์ธกํ๋ ๊ฒ์ด๋ค.
When to use ? Always!
Code we add to tell Typescript what type of value a variable will refer to
type annotation์ด๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ๋ช ์์ ์ผ๋ก ๊ฐ์ด ๊ฐ๋ฅดํค๋ ํ์ ์ ์ง์ ํ๋ ๊ฒ์ด๋ค.
When to use?
- ๋ณ์๋ฅผ ์ ์ธํ๊ณ ๋ค๋ฅธ ๋ผ์ธ์์ ์ด๊ธฐํํ ๋
- Type inference๋ก ์ ํํ ํ์ ์ด ์ฃผ์ด์ง์ง ์์๋
any
ํ์ ์ ๋ฐํํ๋ ํจ์- ๊ฐ์ ๋ช ํํ๊ฒ ํ ํ์๊ฐ ์์๋
const num1: number = 5; // number type์ผ๋ก type annotation
const str: string = 'Hi';
let employee : {
id: number;
name: string;
};
employee = {
id: 100,
name : "John"
}
const json = `{"x": 10, "y": 20}`;
// type annotation์ ํ์ง ์์์๋
const coord = JSON.parse(json);
coord.abc; // undefined, coord๊ฐ abc๋ผ๋ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ง์์ผ๋ฏ๋ก undefiend
// type annotation์ ํ์๋
const coordTyped: {x:number; y:number} = JSON.parse(json);
coord.abc; // error
// Type inference๋ก ์ ํํ ํ์
์ด ์ฃผ์ด์ง์ง ์์ error
let numbers = [-10, -1, 12];
let numberAboveZero = false;
for(let i = 0 ; i < numbers.length; i++) {
if(numbers[i] > 0) {
numberAboveZero = numbers[i];
// error, type inference๋ก ์ ํํ ํ์
์ ์ ์ ์์.
}
}
// Type annotation
let numbers = [-10, -1, 12];
let numberAboveZero: boolean | number = false;
for(let i = 0 ; i < numbers.length; i++) {
if(numbers[i] > 0) {
numberAboveZero = numbers[i];
// error, type inference๋ก ์ ํํ ํ์
์ ์ ์ ์์.
}
}
// ๋น๊ตฌ์กฐ์ (unstructured) annotation
const profile = {
name:'alex',
age: 20
}
const { age }: {age: number} = profile;
tuple์ ๋ฐฐ์ด๊ณผ ์ ์ฌํ์ง๋ง ๊ฐ ์๋ฆฌ๋จผํธ๋ค์ ํ์ ์ ๋ช ์ ํ ์ ์๋ค.
let x: [string, number];
x = ["hello", 2];
enum์ ์ซ์ ๋ฐ์ดํฐ์ ์ ์ด๋ฆ์ ๋ถ์ฌํ๋ ํ์ ์ด๋ค.
enum Color {
Red = 1,
Green,
Blue,
}
let c: Color = Color.Green;
์์ง๋ชปํ๋ ๋ณ์ ์ ํ์ ์ค๋ช ํ๋ ํ์ ์ด๋ค. ์ปดํ์ผ์ ํ์ ๊ฒ์ฌ๋ ํ์ง ์๋๋ค.
์ ๋๋ก ๋ฐ์ํ์ง ์๋ ๊ฐ์ ํ์ ์ด๋ค. ํญ์ ์์ธ๋ฅผ ๋ฐ์์ํค๊ฑฐ๋ ๋ฐํํ์ง์๋ ํจ์ ํํ์์ด๋ ํ์ดํ ํจ์์ ๋ฐํ ์ ํ์ ์ฌ์ฉ๋๋ค.
// Function returning never must not have a reachable end point
function error(message: string): never {
throw new Error(message);
}
// Inferred return type is never
function fail() {
return error("Something failed");
}
// Function returning never must not have a reachable end point
function infiniteLoop(): never {
while (true) {}
}
type array๋ ๊ฐ ์์๊ฐ ํน์ ํ ํ์ ์ ๊ฐ์ธ ๋ฐฐ์ด์ด๋ค.
- ๋ค๋ฅธ ๋ฐฐ์ด ์์๋ค์ ํ์ ๊ณผ ๋ง์ง์๋(imcompatible) ๊ฐ์ด ๋ฐฐ์ด์ ์ถ๊ฐ๋๋๊ฒ์ ๋ง์ ์ ์๋ค.
map
,forEach
,reduce
ํจ์๋ค์ ์ฌ์ฉํ ๋ ๋์์ ์ค๋ค.- ๋ฐฐ์ด์์ ์์๊ฐ extracting ๋ ๋ type inference๋ฅผ ํ ์ ์๊ฒ ๋๋ค.
const arr: string[][] = []; //2์ฐจ์์ string ๋ฐฐ์ด๋ก annotate
arr.push(100); // error
interface๋ ๊ฐ์ฒด์ ํ๋กํผํฐ ์ด๋ฆ๊ณผ ๊ฐ ํ์ ์ ๋ฌ์ฌํ๋ ํ๋์ ํ์ ์ด๋ค.
interface Vehicle {
name: string;
broken: boolean;
}
const oldCivic = {
name: 'civic',
broken:1
}
const printVehicle = (vehicle: Vehicle): void => {
console.log(`Name : ${vehicle.name}`);
console.log(`Broken? : ${vehicle.broken}`);
}
printVehicle(oldCivic); // error,
// Vehicle interface์์ broken์ boolean ํ์
์ผ๋ก annotate ํ์ผ๋ฏ๋ก
// broken์ด number ํ์
์ผ๋ก init๋ oldCivic์ ํ์
๊ฒ์ฌ์์ ๊ฑธ๋ฆฌ๊ฒ ๋จ.
๋ฆฌํฐ๋ด ํ์
์ธ string
๊ณผ number
ํ์
์ ํน์ ๋ฌธ์์ด์ด๋ ์ซ์๋ฅผ ํ์
์ง์ ํ ์ ์๋ค.
let changingString = "Hello World";
changingString = "Ola Mundo";
// let์ผ๋ก ์ ์ธ๋ changingString์ ๋ค๋ฅธ string๊ฐ์ผ๋ก ๊ฐ์ด ๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฏ๋ก string์ผ๋ก inference
// ^ = let changingString: string
const constantString = "Hello World";
// const๋ก ์ ์ธ๋ constantString์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฏ๋ก ๋ฆฌํฐ๋ด ํ์
์ผ๋ก inference
// ^ = const constantString: "Hello World"
๋ค์์ ๋ฆฌํฐ๋ด ํ์ ๊ณผ ์ ๋์ธ์ ๊ฒฐํฉํด ์ฌ์ฉํ๋ ์์ ์ด๋ค.
function textAlignment(s: string, alignment: "left" | "right" | "center") {
// ...
}
textAlignment("Hello, world", "left");
textAlignment("G'day, mate", "centre"); // *1, error
// ๋๋ฒ์งธ ์ธ์๋ "left" ๋๋ "right" ๋๋ "center"๋ก ํ์
annotate ๋๊ธฐ ๋๋ฌธ์ *1์์ error
interface Options {
height: number;
}
function set(x: Options | "auto") {
// ...
}
set({ height: 100 });
set("auto");
set("longer"); // error
๋ฆฌํฐ๋ด inference๋ object
๋ก ๋ณ์๋ฅผ ์ด๊ธฐํ ํ ๋ ํ์
์์คํ
์์ ํด๋น ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ๋์ค์ ๊ฐ์ ๋ฐ๊ฟ์ ์๋ค๊ณ ํ๋จํ๋ ๊ฒ์ด๋ค.
const obj = { amount: 0 };
if (someCondition) {
obj.amount = 1;
}
// ๊ฐ์ฒด ๋ด์ amount๋ฅผ number ๋ฆฌํฐ๋ด ํ์
0์ผ๋ก annotate์ ํ์ง๋ง ๊ฐ์ฒด์ด๋ฏ๋ก ๋์ค์ ๊ฐ์ด ๋ฐ๋์ด์ง ์ ์๊ธฐ๋๋ฌธ์ number๋ก inference๋จ
ํ
ํ๋ฆฟ ๋ฆฌํฐ๋ด ํ์
์ string
๋ฆฌํฐ๋ด ํ์
์ ๊ธฐ๋ฐ์ผ๋ก ์ ๋์ธ์ ํตํด ๋ ๋ง์ ๋ฌธ์์ด๋ก ํ์ฅํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ES6์ ํ ํ๋ฆฟ ๋ฌธ์์ด๊ณผ ๊ฐ์ ๋ฌธ๋ฒ์ ๊ฐ์ง์ง๋ง, type์ ์์น์์ ์ฌ์ฉ๋๋ค.
type World = "world";
type Greeting = `hi ${World}`;
// Greeting์ ํ์
์ 'hello world'
type Apple = "red" | "sweet";
type Lemon = "Yello" | "sour";
type Fruit = `I_like_${Apple | Lemon}_fruit!`;
// Fruit์ ํ์
์ = "red" | "sweet" | "Yello" | "sour"
ํ๋ผ๋ฏธํฐ์ ?
์ ๋ฏธ์ฌ๋ฅผ ์ฌ์ฉํด ํน์ ํ์
์ผ๋ก annotation ํ ๊ฒฝ์ฐ, ๊ทธ ํ๋ผ๋ฏธํฐ๋ ์ค์ ๋ก ํน์ ํ์
๊ณผ undefined
ํ์
์ ๊ฐ์ง๊ฒ ๋๋ค.
์ต์
๋ ํ๋ผ๋ฏธํฐ๋ ์ฌ์ฉ๋์ง ์์๊ฒฝ์ฐ(unused, unspecified) undefined
๊ฐ์ ๊ฐ์ง๋ฉฐ ๊ฐ์ด ์์์๋ ์๊ณ ์์์๋ ์์๋ ์ฌ์ฉํ๋ค.
function point(x?: number, y?: number){
if(x)
console.log('X : ' + x);
else
console.log('Value of X coordinate not given');
if(y)
console.log('Y : ' + y);
else
console.log('Value of Y coordinate not given');
}
// Function Call: point();
Value of X coordinate not given
Value of Y coordinate not given
// Function Call : point(10);
X : 10
Value of Y coordinate not given
// Function Call : point(10, 20);
X : 10
Y : 20
!
๋ฅผ ์ด์ฉํด annotation๋ ํ๋ผ๋ฏธํฐ๋ ํ์
check์ null
๊ณผ undefined
๋ฅผ ํ์ฉํ๋ค.
const v: { p: string | null} = { p: 'text' };
console.log(v.p.toUpperCase()); // Error!
console.log(v.p!.toUpperCase()); // Fine
??
๋ ||
์ฐ์ฐ์์ ๋น์ทํ ๊ธฐ๋ฅ์ผ๋ก null
๋๋ undefined
๊ฐ์ธ์ง ํ์ธํ๋ ์ฐ์ฐ์์ด๋ค.
์ฐ์ฐ์์ ์ผ์ชฝ ๋ณ์๊ฐ null
๋๋ undfined
์ผ ๊ฒฝ์ฐ ์ฐ์ฐ์ ์ฐ์ธก์ ๊ฐ ๋ฐํํ๋ค.
const undefinedVar = undefined;
const value = 'test';
const result = undefinedVar ?? value;
// result === 'test';
!!
์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ฐ์ฐ์๋ก ์ ์๋ ๊ฒ์ ์๋๋ฉฐ ๋ณ์๋ฅผ boolean
ํ์
์ผ๋ก ํ๋ณํํ๋ ์ญํ ์ ํ๋ค.
๊ฐ์ด ํ ๋น๋์ด ์์ผ๋ฉด true
๋ฅผ ๋ฐํ, 0
, null
, undefined
์ ๊ฐ์ ๊ฐ์ง ๊ฒฝ์ฐ false
๋ฅผ ๋ฐํํ๋ค.
const array = [1,2];
!!array[0]; // true
!!array[1]; // true
!!array[2]; // false, undefined
const obj = {
value: 5,
node: null
};
!!obj.value; // true
!!obj.node; // false, null
let v = 0;
!!v // false, 0
- TypeScript
- JS Double Bang โ or โThe Not Operator Part !!โ
- Udemy: React and Typescript: Build a Portfolio Project(by Stephen Grider)