Guide | ๊ธฐ์ต๋ณด๋ค ๊ธฐ๋ก์
Guide ๋ณธ ์นดํ ๊ณ ๋ฆฌ๋ vue.js ์ TypeScript(TS)๋ฅผ ์ ์ฉํ์๋ ์๊ฐ์ผ๋ก TS๋ฅผ ๊ณต๋ถํ๊ณ ๊ธฐ๋กํ ๋ด์ฉ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ์ฌ์ ์ค๋น vue create๋ฅผ ํตํด ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์๋ค๊ณ ๊ฐ์ ํ๊ณ vue.js ์ฝ๋ ์์ ts
kyounghwan01.github.io
โ ๏ธ any ํ์ ์ ์ด๋ ํ ๊ฐ๋ค์ด๋ ๋ฐ์ ์ ์๋ค๊ณ ์ ์ธ๋๋๋ฐ, any๋ฅผ ์ค๊ตฌ๋๋ฐฉ์ผ๋ก ์ฌ์ฉํ ๊ฒฝ์ฐ, VanillaJS์ ๋ค๋ฅธ ์ ์ด ์์ผ๋ฏ๋ก any ํ์ ์ ์ ์ธ์ ํ์ง ์๋ ๊ฒ์ ๊ธธ๋ค์ด์.
์์ฑ์๋ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ type์ ์์ฃผ๋ก ์ด๋ค.
๊ทธ ์ด์ ๋,
interface ์ ์ ํ ๋ง์ฐ์ค๋ฅผ ํธ๋ฒํ์ฌ ํ์ธํ๋ ค๊ณ ํ๋ฉด ํ์ ์ข ๋ฅ๋ฅผ ๋ฐ๋ก ํ์ธ ํ ์ ์๋ ๋ฐ๋ฉด,
type ์ ์ ํ, ๋ง์ฐ์ค ํธ๋ฒ ์ ํ์ ์ ๋ฐ๋ก ํ์ธ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
๐ค ํ์ ์ถ๋ก
ํ์ ์คํฌ๋ฆฝํธ ๋ ๋ณ์๋ฅผ ์ ์ธํ๊ฑฐ๋, ๊ฐ์ ํ ๋น ํ ๋ ์ถ๋ก ์ด ์ผ์ด๋๋ค.
const a = 1;
์ฌ๋์ด ๋ณด์์ ๋, "a์๋ ์ซ์๊ฐ ๋ค์ด๊ฐ๋ ๋ณ์๊ตฌ๋~" ํ๋ ๊ฑฐ ์ฒ๋ผ
ํ์ ์คํฌ๋ฆฝํธ๋ a๋ฅผ number ํ์ ์ด๋ผ๋ ๊ฒ์ ์ถ๋ก ํ๋ค.
ํจ์๋ฅผ ์ ์ธํ ๋์๋ ๋ง์ฐฌ๊ฐ์ง์ด๋ค.
ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ๋ฃ์ผ๋ฉด ์ถ๋ก ์ด ์ผ์ด๋๋ค.
const fx = (a=10) => {
return a;
}
ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํจ์ผ๋ก a๋ number๋ผ๋ ์ถ๋ก ์ด ์ผ์ด๋๋ค.
๐ค ์ธํฐํ์ด์ค ์ถ๋ก
interface User<T> {
name: string;
age: number;
address: T;
}
interface UserIdentityCard<K> extends User<K> {
id: K
// ์์ User<T> ํ์
์ ๊ทธ๋๋ก ์ ์ฉ
// name: string;
// age: number;
// address: K
}
const ํ๊ธธ๋: User<string> = {
name: "ํ๊ธธ๋",
age: 29,
address: "Chosun"
}
const ํ๊ธธ๋๋ฏผ์ฆ: UserIdentityCard<string> = {
id: "139200-191000",
name: "ํ๊ธธ๋",
age: 29,
address: "Chosun"
}
์ ๋ค๋ฆญ๊ฐ์ ๋ฐ๋ผ์ ์ ๋ ฅ๋ string ๊ฐ์ด ์ ์ฉ๋๋ค.
๐ค Best Common Type ์ถ๋ก
๋ฐฐ์ด ์์ ์ฌ๋ฌ ํ์ ์ด ์ ์๋ ๊ฒฝ์ฐ ์ถ๋ก ์ ์ ๋์จ ํ์ ์ผ๋ก ์ ์๋๋ค.
const arr = [1, true, "a"];
ํด๋น arr๋ Array<number | boolean | string> ํน์ (number | boolean | string)[] ์ผ๋ก ์ถ๋ก ๋๋ค.
์ถ๋ก ์ ์์ ๋ณ์์ ๊ฐ๋ฐ์๊ฐ ํ์ ์ ์ ์ํ ์๊ณ ๋ฅผ ๋์ด์ค๋ค.
๐๐ป ํ์ ๋จ์ธ (Type Assertion)
ํ์ ์คํฌ๋ฆฝํธ์์ ์ถ๋ก ํ๋ ๊ฐ๋ณด๋ค ๊ฐ๋ฐ์๊ฐ ํด๋น ๋ณ์ ํ์ ์ ๋ ์ ์๊ณ ์์ ๋ ๋ณ์์ ์ํ๋ ํ์ ์ ๊ฐ์ ๋ก ๋ถ์ฌํ๋ค.
let a;
a = "Hello, World!"
a = 10;
let b = a;
// ์ด๋ ํ์
์คํฌ๋ฆฝํธ๋ a๊ฐ ์ด๋ ํ ๊ฐ์ด ๋ด๊ธธ ๋ณ์์ธ์ง ์ ํํ ์ธ์งํ์ง ๋ชปํ์ฌ any๋ก ์ถ๋ก ํ๋ค.
// ์ฆ b๋ any ํ์
์ผ๋ก ์ถ๋ก ์ ํ๊ฒ ๋๋๋ฐ.
// ์ฐ๋ฆฌ๋ b์ number์์ ์๊ธฐ์ number๋ฅผ ๊ฐ์ ๋ก Assertionํ๋ค.
b = a as number;
as <T> ๋ฅผ ํตํ์ฌ ํด๋น ๊ฐ์ด numberํ์ ์์ ํ์ ์คํฌ๋ฆฝํธ์๊ฒ ์๋ ค์ค๋ค.
๊ฐํน ๊ฐ๋ฐํ๋ค ์ถ๋ก ์ ์คํจํ์ฌ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๋ as <T> ๋ฅผ ํตํ์ฌ ๋ฆฐํ ์ค๋ฅ๋ฅผ ํด๊ฒฐํ๋ค.
DOM์ ์ ๊ทผํ ๋ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ค.
import { useEffect } from 'react'
function Home() {
useEffect(() => {
// ๋ง์ดํธ๋ DOM์ด ์๋๋ผ๋ฉด useEffect๋ฅผ ํตํด ๋ง์ดํธ ๋ ๋ค์ DOM์ ์ฐพ์์ฃผ์
// โ ๏ธ Type1. id๊ฐ์ผ๋ก ์ฐพ์ Element๊ฐ ์์ ์ ์๋ค๋ ์ค๋ฅ
const box = document.getElementybyId("box");
box.innerText = "content"; // error: Object is possible null;
// โ
Type2. ์กฐ๊ฑด๋ฌธ์ ํตํ์ฌ Element๊ฐ ์กด์ฌํ ๋ ์์
const box = document.getElementybyId("box");
if(box) {
box.innerText = "content";
}
// โ
Type3. box๊ฐ ๋ง์ดํธ ๋ ํ, ๋ฌด์กฐ๊ฑด ์กด์ฌํ๋ค๋ ์ํฉ์์ ์๋ฆผ
const box = document.getElementybyId("box") as HTMLDivElement;
box.innerText = "content";
}, [])
return <div id="box"></div>
}
๐ก๏ธ ํ์ ๊ฐ๋ (Type Guard)
ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋์จ ํ์ ์ด ์ง์ ๋ ๊ฒฝ์ฐ ํ์ ์ด 2๊ฐ ์ด์์์ผ๋ก ๊ณตํต๋๋ ์์ฑ๋ง ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
type NPC = {
name: string;
gender: "M" | "F";
}
type User = {
name: string;
gender: "M" | "F";
skill: string[];
}
function getInstance(): NPC | User {
return { name: "๊ฐ๋ฐ์", gender: "M", skill: ['ctrl-C', 'ctrl-V'] };
}
const dev = getInstacne(); // NPC | User์ ๊ณตํต๋ ์์ฑ๋ง ์ฌ์ฉ ๊ฐ๋ฅ. (or ์ฐ์ฐ์)
// dev ๊ฐ์ฒด์ ์ ๊ทผํ๊ธฐ ์ํด .์ ์ฐ์ผ๋ฉด
// intellgence ๊ณตํต์ธ name๊ณผ gender๋ง ํ์.
// skill์ ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ, Assertion์ ์ฌ์ฉํ ๊ฒฝ์ฐ
if ((dev as User).skill) {
console.log((dev as User).skill);
} else {
console.log('์ NPC๋ค');
}
// ํ์
๊ฐ๋ ์ ์
function getInstanceWithGuard(target: NPC | User): target is User {
return (target as User).skill !== undefined
}
if(getInstanceWithGuard(dev)) {
console.log(dev.skill)
} else {
console.log('์ NPC๋ผ๊ณ ');
}
๐ญ ๊ธฐ๋ณธ ํ์
โญโ boolean
const bool: boolean = true; // true or false
๐ข number
// ์ ์, ์ค์ ๋ชจ๋ number๋ก ํ๊ธฐ
const naturalNumber: number = 100;
const integer = 0.123;
๐ป null / undefined
const a: null = null;
const b: undefined = undefined;
โ ๏ธ Object
// ํ์
const required: { name: string; age: number } = { name: 'dev', age: 29 };
// ํ์ ์์ฑ์ด์ง๋ง ๋ฐ๋ก ์ ์ํ๊ณ ์ถ์ง ์์ ๊ฒฝ์ฐ
const required = {} as { name: string; age:number };
// ์ ํ
const optional: {name: string; age?: number } = { name: 'dev' };
// (Partial) ํ์ ์์ฑ์ผ๋ก ์ ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ ํ ์์ฑ์ผ๋ก
const partial: Partial<{name: string; age: number }> = {};
// ์ฝ๊ธฐ ์ ์ฉ ReadOnly
// readonly.name = "junior" ๋ก ์ฌํ ๋น ๋ถ๊ฐ
const readonly: {readOnly name: string} = { name: 'dev' };
// Empty Object ํ์
const emptyObject: Recored<string, never> = {};
๐ Array
// string ํ์
๋ง ๋ฐ๋ ๋ฐฐ์ด
const onlyString: string[] = ["a", "b"];
const onlyArrayString: Array<string> = ["a", "b"];
// number ํ์
๋ง ๋ฐ๋ ๋ฐฐ์ด
const onlyNumber: number[] = [1, 2];
const onlyArrayNumber: Array<number> = [1, 2];
๐ Tuble
๋ฐฐ์ด์ ๊ธธ์ด๊ฐ ๊ณ ์ ๋๊ณ , ๊ฐ ์์์ ํ์ ์ด ์ง์ ๋์ด ์๋ ๋ฐฐ์ด ํ์์ด๋ค.
const tuple: [string, number] = ["str", 10];
๐ Enum
์์์ ์งํฉ์ผ๋ก, HTML์ option ํ๊ทธ ๊ฐ์ด ์ด๋ ํ ์ข ๋ฅ์ ๋ํ ์ง์ ๋ ํ์ ์ด ๋ค์ด์ฌ ๊ฒฝ์ฐ ํ๋ฆฐ ์์ ๊ฐ์ด ๋ค์ด์ค๋ ๊ฒ์ ๋ง๊ธฐ ์ํ์ฌ Enum์ผ๋ก ์์์ ์งํฉ์ ๋ง๋ค๊ณ , ๊ทธ ์ด์ธ์ ๊ฐ์ ๋ฐ์ง ์๋๋ค.
enum ColorPalette {
Red: "red",
Green: "green",
Blue: "blue"
}
const color: ColorPalette = ColorPlatte.Red;
๐คท๐ปโ๏ธ any
๋ง ๊ทธ๋๋ก ์ด๋ ํ ํ์ ์ด๋ ํ์ฉํ๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ ํ์ผ์ ํ์ ์คํฌ๋ฆฝํธ๋ก ๋ฐ๊ฟ ๊ฒจ์ฐ ํ ๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ์ ์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด ์ด๋ ต๊ธฐ์ ์ฒ์ฒํ ํ์ ์ ์ ์ฉํ๊ธฐ ์ํด ์ผ๋จ ๋ชจ๋ ๋ฐ์ดํฐ์ any๋ฅผ ์ ์ฉ ํ, ์ ์ง์ ์ผ๋ก ํ์ ์ผ๋ก ๊ฐ์ ์ ์ฉ.
โ ๏ธํ์ ์คํฌ๋ฆฝํธ๋ก ํ๋ก์ ํธ๋ฅผ ์์ํ ๋๋ ์ฌ์ฉํ์ง ์๋๋ก ํ๋ค.
const anyType: any = ["any", "body~", 123, true];
๐ป void
๋ณ์์๋ undefined, null๋ง ํ ๋น ๊ฐ๋ฅํ๊ณ , ํจ์์๋ return ๊ฐ์ด ์์ ๊ฒฝ์ฐ ์ค์ ํ๋ ํ์ ์ด๋ค.
const unuseData: void = undefined;
const notReturnValue(): void {
console.log('๋ฐํ ์์');
}
๐ never
ํด๋น ํจ์์ ๋งจ ๋ง์ง๋ง๊น์ง ๋๋ฌํ์ง ์๋๋ค๋ ํ์ ์ผ๋ก ์ ๋ ๋ฐ์ํ์ง ์๋ ๊ฐ์ผ๋ก ์๋ฌ ํธ๋ค๋ง ํจ์์์ ์ฌ์ฉํ๋ค.
์ฃผ๋ก ํจ์์ ๋ฆฌํด ํ์ ์ผ๋ก ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์๋ฌ๋ฅผ ๋ฌด์ํ๊ณ ๊ณ์ ์งํ์ํค๋ ์ญํ ์ ํ๋ค.
๋๋ ๋์ฒด ๋ถ๊ฐํ ๊ฐ์ ๋ง๋ค ๋ ์ฌ์ฉํ๋ค. -> ์ฌํ ๋น ๋ถ๊ฐ
// ์ด ํจ์๋ ์ ๋ ํจ์์ ๋๊น์ง ์คํ๋์ง ์๋๋ค๋ ์๋ฏธ
const nerverEnd = (): never => {
while(true) {
...
}
// ๋๋ฌํ์ง ์์
}
const errorThrow = (): never => {
// ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ค์งํ์ง ์๊ณ throw ํจ์ ์คํ
throw new Error("error");
}
๐ Union
union ํ์ ์ ํ๋์ ๋ณ์์ ์ฌ๋ฌ ํ์ ์ ์ง์ ํ ์ ์๋ค.
์ฌ๋ฌ ํ์ ์ ์ง์ ํ๊ณ ์ถ์ ๊ฒฝ์ฐ " | " ๋ฅผ ์ฌ์ฉํ๋ค.
let unionType: string | number = "str";
unionType = 123;
unionType = "word";
unionType = true; // error
๐ Union ์ธํฐ์ ์
" | "๊ฐ OR ์ด๋ผ๋ฉด " & "๋ AND ์ด๋ค.
type User = {
name: string
age: number
gender: 'male' | 'female'
}
type Robot = {
name: string;
age: number;
}
const printCommon = (someone: User | Robot) =>{
console.log(someone.name);
// ๊ณตํต์ผ๋ก ์ ์๋ ๋ด์ฉ๋ง ํ์ฉ
}
const printDiff = (someone: User & Robot) =>{
console.log(someone.gender)
// ๋ ํ์
์ ๋ชจ๋ ๋ด์ฉ์ ํ์ฉ
}
๐ก๏ธ union Type Guard
์ฌ๋ฌ ํ์ ์ ์ฌ์ฉํ๋ฉด ํด๋น ๊ฐ์ ํ์ ์ ๋ฐ๋ผ ๋ถ๊ธฐ ์ฒ๋ฆฌํ ๋๊ฐ ๋ฐ์ํ๋ค.
์ด๋ด ๊ฒฝ์ฐ ๊ฐ ํ์ ์ ๋ฐ๋ผ ์กฐ๊ฑด๋ฌธ์ ๋ง๋ค์ด์ฃผ๋ฉด ๋๋ค.
type functionProps = {
value: string | number;
}
function fx(value: functionProps): number {
if(typeof value === 'string') {
return value.length;
}
return value;
}
๐ข declare
์ ์ญ๋ณ์๋ฅผ ๋ง๋ค๊ฑฐ๋, ๐*.d.ts ๋ฅผ ๋ง๋ค ๋ ์ฌ์ฉํ๋ค.
import ํ ํ์ ์์ด, typescript ํ๋ก์ ํธ์๊ฒ ์ด๋ฌํ ํ์ ์ด ์๋ค๊ณ ๋ฏธ๋ฆฌ ์ ์ํ์ฌ ์ฌ์ฉํ๋ค.
์ง๋๋งต์ ๊ทธ๋ฆฐ๋ค๊ณ ๊ฐ์ ํ์์ ๋,
๐type.d.ts
declare function setupMap(config: MapConfig): void;
interface MapConfig {
lng: number;
lat: number;
tileSize: 8 | 16 | 32;
}
๐App.tsx
// prev code...
// import ์์ด ์ฌ์ฉ ๊ฐ๋ฅ
setupMap({
lng: 10,
lat: 10,
tileSize: 8
})
// next code ...
๐ญ class protected ๋ณ์
protected๋ก ์ ์ธ๋ ๋ฉค๋ฒ๋ฅผ ํ์๋ ํด๋์ค์์ ์ ๊ทผํ ์ ์๋ค๋ ์ ๋ง ์ ์ธํ๋ฉด private ์ง์ ์์ ๋งค์ฐ ์ ์ฌํ๋ค.
//private
class User {
#name: string;
//private name: string;
constructor(name: string) {
this.#name = name;
}
getName() {
return this.#name
}
}
class Employee extedns User {
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
public intoduce() {
//โ Error. ํ์๋ class์์๋ private๋ ์ ๊ทผ ๋ถ๊ฐ
return `Hello, My name is ${this.name} and I work in ${this.department}.`;
}
}
const user = new Employee('dev', 'computer');
โ
user.getName();
โ
user.introduce();
โ user.#name
//protected
class User {
protected name: string;
constructor(name: string) {
this.#name = name;
}
getName() {
return this.#name
}
}
class Employee extedns User {
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
public intoduce() {
//โ
protected๋ ์์๋ฐ์ ์ฌ์ฉ ๊ฐ๋ฅ
return `Hello, My name is ${this.name} and I work in ${this.department}.`;
}
}
const user = new Employee('dev', 'computer');
โ
user.getName();
โ
user.introduce();
โ
user.name
'Language > TypeScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ TypeScript ] ํ์ ์คํฌ๋ฆฝํธ์ ๋ํด ์์๋ณด์. (0) | 2024.03.06 |
---|