![[Typescript] ์ธํฐํ์ด์ค(1)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb0jm1%2FbtsI5ymHLpV%2FOuHJi6ygt0xK5xSTdP81v1%2Fimg.png)
๐์๋ก
์ธํฐํ์ด์ค๋ ์ฐ๊ด๋ ์ด๋ฆ์ผ๋ก ๊ฐ์ฒด ํํ๋ฅผ ์ค๋ช ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ธํฐํ์ด์ค๋ ๋ณ์นญ์ผ๋ก ๋ ๊ฐ์ฒด ํ์ ๊ณผ ์ฌ๋ฌ๋ฉด์์ ์ ์ฌํ๋ค.
ํ์ง๋ง ์ผ๋ฐ์ ์ผ๋ก
โ ์ฝ๊ธฐ ์ฌ์ด ์ค๋ฅ ๋ฉ์์ง
โก ๋น ๋ฅธ ์ปดํ์ผ๋ฌ ์ฑ๋ฅ
โข ํด๋์ค์์ ๋ ๋์ ์ํธ ์ด์ฉ์ฑ
3๊ฐ์ง์ ์ฅ์ ์ ๊ฐ์ง๋ค.
1๏ธโฃํ์ ๋ณ์นญ vs ์ธํฐํ์ด์ค
ํ์ ๋ณ์นญ
type Poet = {
born: number;
name: string;
};
์ธํฐํ์ด์ค
interface Poet {
born : number;
name : string;
}
TypeScript์ ํ ๋น ๊ฐ๋ฅ์ฑ ๊ฒ์ฌ์ ์ค๋ฅ ๋ฉ์์ง๋ ๊ฐ์ฒด ํ์ ๋ณ์นญ์์์ ๊ฒฝ์ฐ์ ๊ฑฐ์ ๋์ผํ๋ค.
ํ์ง๋ง ์ธํฐํ์ด์ค์ ํ์ ๋ณ์นญ ์ฌ์ด์๋ 4๊ฐ์ง ์ฃผ์ ์ฐจ์ด์ ์ด ์๋ค.
โจ 4๊ฐ์ง ์ฐจ์ด์
1๏ธโฃ ์ธํฐํ์ด์ค๋ ์์ฑ ์ฆ๊ฐ๋ฅผ ์ํด ๋ณํฉ(merge)ํ ์ ์๋ค. ์ด ๊ธฐ๋ฅ์ ๋ด์ฅ๋ ์ ์ญ ์ธํฐํ์ด์ค ๋๋ npmํจํค์ง์ ๊ฐ์ ์ธ๋ถ ์ฝ๋๋ฅผ ์ฌ์ฉํ ๋ ํนํ ์ ์ฉํ๋ค.
/* node_modules/@types/express/index.d.ts ์ ์ ์๋ Request ์ธํฐํ์ด์ค์ ์ผ๋ถ */
import { Request as ExpressRequest } from 'express';
declare module 'express-serve-static-core' {
interface Request {
/* ๊ธฐ๋ณธ์ ์ผ๋ก ํฌํจ๋ ์์ฑ๋ค */
body: any;
params: any;
query: any;
}
}
์ด ์ฝ๋๋ Express.js์ Request ์ธํฐํ์ด์ค์ ๊ธฐ๋ณธํํ์ด๋ค.
์ด ์ธํฐํ์ด์ค์ ์์ฑ์ ์ปค์คํ ํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉํ๋ค.
import { Request as ExpressRequest } from 'express';
/* ๊ธฐ์กด์ Request ์ธํฐํ์ด์ค์ ์๋ก์ด ์์ฑ์ ์ถ๊ฐ */
declare module 'express-serve-static-core' {
interface Request {
user?: {
id: string;
name: string;
email: string;
};
}
}
/* ์์ ์ฌ์ฉ ์ฝ๋ */
import express from 'express';
const app = express();
app.use((req, res, next) => {
/* req.user์ ์ฌ์ฉ์ ์ ๋ณด ์ ์ฅ */
req.user = {
id: '123',
name: 'Alice',
email: 'alice@example.com',
};
next();
});
app.get('/', (req: ExpressRequest, res) => {
/* req.user๋ฅผ ํ์
์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ */
res.send(`Hello ${req.user?.name}`);
});
์ด๋ ๊ฒ ์ธํฐํ์ด์ค์ ์์ฑ์ ์ถ๊ฐํ๊ณ ์ฌ์ฉํ๋ฉฐ ํ์ ์ ๋ํ ์์ ์ฑ๊ณผ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์ด ํด๋ฆฐ์ฝ๋๋ฅผ ๋ง๋ค ์ ์๋ค.
2๏ธโฃ ์ธํฐํ์ด์ค๋ ํด๋์ค๊ฐ ์ ์ธ๋ ๊ตฌ์กฐ์ ํ์ ์ ํ์ธํ ์ ์์ง๋ง ํ์ ๋ณ์นญ์ ๋ถ๊ฐ๋ฅ ํ๋ค.
์ธํฐํ์ด์ค๋ก ํ์ ํ์ธ
interface Person {
name: string;
age: number;
}
class Employee implements Person {
constructor(public name: string, public age: number) {}
}
const emp: Person = new Employee('Alice', 30);
console.log(emp.name); /* 'Alice' */
console.log(emp.age); /* 30 */
์ธํฐํ์ด์ค๋ ํด๋์ค๊ฐ ํน์ ๊ตฌ์กฐ(ํ๋กํผํฐ์ ๋ฉ์๋)๋ฅผ ๋ฐ๋ผ์ผ ํ๋์ง ๊ฐ์ ํ ์ ์์ผ๋ฉฐ, ํด๋์ค๊ฐ ๊ทธ ๊ตฌ์กฐ๋ฅผ ์ถฉ์กฑํ๋ฉด ํ์ ์ฒดํฌ๋ฅผ ํต๊ณผํ๋ค.
ํ์ ๋ณ์นญ์ผ๋ก ํ์ ํ์ธ
type PersonType = {
name: string;
age: number;
}
class EmployeeType {
constructor(public name: string, public age: number) {}
}
/* ํ์
๋ณ์นญ์ ํด๋์ค๋ฅผ ํ์
์ผ๋ก ์ฌ์ฉํ ์๋ ์์ง๋ง,
ํ์
๋ณ์นญ์ ํด๋์ค์ ์ง์ ์ ์ผ๋ก ์ฐ๊ฒฐํ๊ฑฐ๋ implements ํ ์๋ ์๋ค.*/
const empType: PersonType = new EmployeeType('Bob', 25);
console.log(empType.name); /* 'Bob' */
console.log(empType.age); /* 25 */
ํ์ ๋ณ์นญ์ ํด๋์ค์ ๊ตฌ์กฐ๋ฅผ ํ์ธํ ์ ์์ผ๋ฉฐ, ๋จ์ํ ๊ตฌ์กฐ์ ์ธ ํ์ ์ ์๋ก ์ฌ์ฉ๋๋ค.
3๏ธโฃ์ธํฐํ์ด์ค์์ TypeScript ํ์ ๊ฒ์ฌ๊ธฐ๊ฐ ๋ ๋นจ๋ฆฌ ์๋ํ๋ค.
์ธํฐํ์ด์ค๋ ํ์ ๋ณ์นญ์ด ํ๋ ๊ฒ์ฒ๋ผ ์๋ก์ด ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋์ ์ธ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ๋ณด๋ค ๋ด๋ถ์ ์ผ๋ก ๋ ์ฝ๊ฒ ์บ์ํ ์ ์๋ ๋ช ๋ช ๋ ํ์ ์ ์ ์ธํ๋ค.
๐ ํ์ ๋ณ์นญ์ด TypeScript ์ปดํ์ผ๋ฌ์์ ๋์ํ๋ ๋ฐฉ์
type UserAlias = {
id: number;
name: string;
email: string;
};
type AdminAlias = {
id: number;
name: string;
email: string;
role: string;
};
const user: UserAlias = { id: 1, name: 'Alice', email: 'alice@example.com' };
const admin: AdminAlias = { id: 2, name: 'Bob', email: 'bob@example.com', role: 'admin' };
1. ๋์ ๋ณต์ฌ
ํ์ ๋ณ์นญ์ ์ฌ์ฉํ ๋, UserAlias๋ AdminAlias ๊ฐ์ ํ์ ์ ์๋ ๊ฐ ์ฌ์ฉ ์ง์ ์์ ํด๋น ํ์ ์ ๊ตฌ์กฐ๋ฅผ ์ง์ ์ ์ผ๋ก ์ฌ์ฉํ๋ค. ์ปดํ์ผ๋ฌ๋ ์ด ํ์ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋๋ก ๊ฐ์ ธ์์ ์ฌ์ฉํ ์๋ฐ์ ์๋ค.
์ด๋ ์ปดํ์ผ๋ฌ๊ฐ ๋ง์น ์ด ๊ตฌ์กฐ๋ฅผ ๋ณต์ฌํด์ ์ฌ์ฉ ์ง์ ์ ๋ถ์ฌ๋ฃ๋ ๊ฒ๊ณผ ๊ฐ๋ค.
2. ์ค๋ณต๋ ์ ์
๋ง์ฝ ์ฌ๋ฌ ๊ณณ์์ ๋์ผํ ํ์ ๋ณ์นญ์ ์ฌ์ฉํ๋ค๋ฉด, ์ปดํ์ผ๋ฌ๋ ์ด ๊ตฌ์กฐ๋ฅผ ๋งค๋ฒ ์๋ก ํด์ํ๊ฒ ๋๋ค.
์ฆ, AdminAlias์์ UserAlias์ ์ ์ฌํ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ณ ์์ง๋ง, ํ์ ๋ณ์นญ์ ์ปดํ์ผ๋ฌ๊ฐ ์ด๋ฅผ ์บ์ํ๊ฑฐ๋ ์ต์ ํํ์ง ์์ผ๋ฏ๋ก, ์ฝ๋์ ๊ฐ ์ฌ์ฉ ์ง์ ์์ ์ด ๊ตฌ์กฐ๋ฅผ ๋ค์ ๋ณต์ฌํด์ ํด์ํ๋ ๊ฒ์ฒ๋ผ ๋์ํ๋ค.
๐ ์ธํฐํ์ด์ค๊ฐ TypeScript ์ปดํ์ผ๋ฌ์์ ๋์ํ๋ ๋ฐฉ์
์ธํฐํ์ด์ค๋ "๋ช ๋ช ๋ ํ์ " ์ด๋ฏ๋ก ์ปดํ์ผ๋ฌ๊ฐ ์ด๋ฅผ ํ ๋ฒ ์ ์ํ๊ณ ๋๋ฉด ์ฌ๋ฌ ๊ณณ์์ ์ฌ์ฌ์ฉํ ๋ ์บ์ํ์ฌ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค.
interface UserInterface {
id: number;
name: string;
email: string;
}
interface AdminInterface extends UserInterface {
role: string;
}
์ ์ฝ๋์์๋ AdminInterface๊ฐ UserInterface๋ฅผ ํ์ฅํ๋ค.
UserInterface์ ๊ตฌ์กฐ๊ฐ ํ ๋ฒ ์ ์๋๊ณ , AdminInterface์์ ์ด๋ฅผ ์ฌ์ฌ์ฉํ๋ฏ๋ก, ์ปดํ์ผ๋ฌ๋ ์ด ๊ตฌ์กฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์บ์ํ๋ฉฐ ํ์ ๋ณ์นญ๋์ ๊ฐ์ด ๋ฐ๋ณต์ ์ผ๋ก ํด์ํ ํ์๊ฐ ์๋ค.
4๏ธโฃ ์ธํฐํ์ด์ค๋ ์ด๋ฆ ์๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๋ณ์นญ์ด ์๋ ๋ช ๋ช ๋ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ๋๋ฏ๋ก ์ฌ๋ฌ์ด ํน์ด ์ผ์ด์ค์์ ๋ํ๋๋ ์ค๋ฅ ๋ฉ์์ง์ ๊ฐ๋ ์ฑ์ด ์ข๋ค.
/* ํ์
๋ณ์นญ */
type UserAlias = {
id: number;
name: string;
email: string;
};
function processUserAlias(user: UserAlias) {
/* UserAlias ํ์
์ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์ */
console.log(user);
}
/* ์ธํฐํ์ด์ค */
interface UserInterface {
id: number;
name: string;
email: string;
}
function processUserInterface(user: UserInterface) {
/* UserInterface ํ์
์ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ๋ ํจ์ */
console.log(user);
}
/* ์ค๋ฅ ๋ฐ์ ์๋๋ฆฌ์ค */
/* ํ์
๋ณ์นญ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ */
processUserAlias({
id: 1,
name: 'Alice',
/* 'email' ์์ฑ์ด ๋น ์ก์ต๋๋ค. TypeScript๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. */
});
/* ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ */
processUserInterface({
id: 1,
name: 'Bob',
/* 'email' ์์ฑ์ด ๋น ์ก์ต๋๋ค. TypeScript๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. */
});
ํ์ ๋ณ์นญ ์๋ฌ๋ฉ์์ง
Argument of type '{ id: number; name: string; }' is not assignable to parameter of type 'UserAlias'.
Property 'email' is missing in type '{ id: number; name: string; }' but required in type 'UserAlias'.
๊ธฐ๋ณธ์ ์ผ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๊ตฌ์กฐ์ ํ์ ๋ณ์นญ์ ์ด๋ฆ์ ๋ณด์ฌ์ค๋ค.
๊ทธ๋ฌ๋ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ด ๋ณต์กํด์ง๋ฉด, ์ค๋ฅ ๋ฉ์์ง๊ฐ ๋ ๊ธธ๊ณ ๋ณต์กํด์ง ์ ์๋ค.
์ธํฐํ์ด์ค ์๋ฌ๋ฉ์์ง
Argument of type '{ id: number; name: string; }' is not assignable to parameter of type 'UserInterface'.
Property 'email' is missing in type '{ id: number; name: string; }' but required in type 'UserInterface'.
์ด ๋ฉ์์ง๋ ๋ช ๋ช ๋ ์ธํฐํ์ด์ค(UserInterface)๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์, ํ์ ๊ตฌ์กฐ๋ฅผ ๋ช ํํ๊ฒ ์ธ์ํ ์ ์๊ฒ ํด์ค๋ค.
์ด๋ก ์ธํด ๊ฐ๋ฐ์๊ฐ ์ค๋ฅ์ ์์ธ์ ๋ ์ฝ๊ฒ ํ์ ํ ์ ์๋ค.
ํ์ ๋ณ์นญ์ ์ ๋์ธ ํ์ ๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ด ํ์ํ ๋ ๊น์ง๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
2๏ธโฃ์์ฑ ํ์
2๏ธโฃ - 1. ์ ํ์ ์์ฑ
๊ฐ์ฒดํ์ ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ชจ๋ ๊ฐ์ฒด๊ฐ ํ์์ ์ผ๋ก ์ธํฐํ์ด์ค ์์ฑ์ ๊ฐ์ง ํ์๋ ์๋ค.
๊ทธ๋์ TypeScript๋ ์ ํ์ ์์ฑ์์ ๋ํ๋ผ ์ ์๋๋ฐ, ์ ์ธ ๋ฐฉ์์ ํ์ ์ ๋ํ ์ด์ : ์์ ?๋ฅผ ์ฌ์ฉํค ์ธํฐํ์ด์ค์ ์์ฑ์ด ์ ํ์ ์์ฑ์์ ๋ํ๋ผ ์ ์๋ค.
interface Book {
author: string;
pages : number;
translator?: string;
}
const Book1:Book={
author: "Danny",
pages: 25,
translator: "Kim"
}
/* OK */
const Book2:Book={
author: "Jenny",
pages: 25,
}
/* OK */
2๏ธโฃ - 2. ์ฝ๊ธฐ ์ ์ฉ ์์ฑ
๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ธํฐํ์ด์ค์ ์ ์๋ ๊ฐ์ฒด์ ์์ฑ์ ์ฌํ ๋นํ์ง ๋ชปํ๋๋ก ์ฐจ๋จํ๊ณ ์ถ์๋ ์ฌ์ฉํ๋ค.
readonly ํค์๋๋ฅผ ์์ฑ์์ ์ถ๊ฐํด ๋ค๋ฅธ๊ฐ์ผ๋ก ์ค์ ํ ์ ์์์ ๋ํ๋ธ๋ค.
interface Page {
readonly text: string;
}
function read(page:Page){
console.log(page.text);
let pageText = page.text;
console.log(pageText);
/* OK */
page.text += "."
/*
Error: Cannot assign to text because it is a read-only property.
*/
}
readonly ์ ํ์๋ ํ์ ์์คํ ์๋ง ์กด์ฌํ๋ฉฐ ์ธํฐํ์ด์ค์์๋ง ์ฌ์ฉํ ์ ์๋ค.
readonly ์ ํ์๋ ๊ฐ์ฒด์ ์ธํฐํ์ด์ค๋ฅผ ์ ์ธํ ๋๋ง ์ฌ์ฉ๋๋ฉฐ ์ค์ ๊ฐ์ฒด์๋ ์ ์ฉํ์ง ์๋๋ค.
์๋์ ์ฝ๋ ์์ ๋ฅผ ๋ณด์.
interface Page {
readonly text: string;
}
function read(page:Page){
console.log(page.text);
let pageText = page.text;
console.log(pageText);
}
/* OK */
const pageIsh = {
text:"Hello world"
}
/* OK */
pageIsh.text += "!!";
read(pageIsh);
ํจ์ ๋ด๋ถ์์ pageIsh.text๋ฅผ ์ฝ๊ธฐ๋ง ํ๊ณ ์์ ํ์ง ์๊ธฐ ๋๋ฌธ์, ํจ์ ์ธ๋ถ์์ pageIsh.text๋ฅผ ์์ ๋กญ๊ฒ ์์ ํ ์ ์๋ค๋ ๋ป์ด๋ค.
- ํจ์ ๋ด๋ถ์์์ ๋์: read ํจ์๋ pageIsh ๊ฐ์ฒด๋ฅผ ๋ฐ์์ ๊ทธ ๊ฐ์ฒด์ text ์์ฑ์ ์ฝ์์ ์ถ๋ ฅํ๋ค. ํจ์๋ text ์์ฑ์ ์์ ํ์ง ์๊ณ ๋จ์ํ ์ฝ๊ธฐ๋ง ํ๋ค.
- ํจ์ ์ธ๋ถ์์์ ๋์: pageIsh.text += "!!"; ์ฝ๋์์ text ์์ฑ์ ์์ ํ๊ณ ์๋ค. ์ด ์ฝ๋๊ฐ ํจ์ ์ธ๋ถ์์ ์คํ๋๊ธฐ ๋๋ฌธ์ readonly ์์ฑ์ ์ ์ฝ์ ๋ฐ์ง ์๋๋ค.
์ ์ด๋ฐ ์ผ์ด ๊ฐ๋ฅํ๊ฐ?
Page ์ธํฐํ์ด์ค์์๋ text ์์ฑ์ readonly๋ก ์ง์ ํ์ง๋ง, pageIsh ๊ฐ์ฒด ์์ฒด๋ Page ์ธํฐํ์ด์ค์ ์๊ฒฉํ ๊ตฌํ์ฒด๊ฐ ์๋๋ค.
์ฆ, pageIsh ๊ฐ์ฒด์ text ์์ฑ์ readonly๊ฐ ์๋๋ฏ๋ก, ์ธ๋ถ์์ ์์ ๋กญ๊ฒ ์์ ํ ์ ์๋ค.
ํจ์ ๋ด๋ถ์์ text๋ฅผ ์์ ํ์ง ์๊ธฐ ๋๋ฌธ์ TypeScript๋ ์ด ๊ฐ์ฒด๊ฐ Page ์ธํฐํ์ด์ค์ ํธํ๋๋ค๊ณ ํ๋จํ๋ ๊ฒ์ด๋ค.
readonly๋ ์ฝ๋์์ญ์์ ๊ฐ์ฒด๋ฅผ ์๋์น ์๊ฒ ์์ ํ๋ ๊ฒ์ ๋ง๋ ํธ๋ฆฌํ ๋ฐฉ๋ฒ์ด๋ค. ๊ทธ๋ฌ๋ readonly๋ ์ปดํ์ผ๋ JavaScript์ฝ๋์๋ ์กด์ฌํ์ง ์๋๋ค.
์ฆ, readonly์ ํ์๋ ํ์ ๊ฒ์ฌ๊ธฐ๋ฅผ ์ฌ์ฉํด ๊ฐ๋ฐ์ค์ ๊ทธ ์์ฑ์ด ์์ ๋์ง ์๊ฒ ํ๋ ์ญํ ๋ง ์ํํ๋ค.
2๏ธโฃ - 3. ํจ์์ ๋ฉ์๋
TypeScript์์๋ JavaScript์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ธํฐํ์ด์ค ๋ฉค๋ฒ๋ฅผ ํจ์ํ์ ์ผ๋ก ์ ์ธํ ์ ์๋ค.
๋ฐฉ๋ฒ์ 2๊ฐ์ง๊ฐ ์๋ค.
- ๋ฉ์๋ ๊ตฌ๋ฌธ
- ์์ฑ ๊ตฌ๋ฌธ
interface HasBothFunctionTypes {
property : () => string;
method() : string;
}
const hasBoth : HasBothFunctionTypes = {
property : () => "",
method(){
return "";
}
};
hasBoth.property(); /* OK */
hasBoth.method(); /* OK */
ํจ์์์ฑ ๋ํ ์ ํ์ ์์ฑ์ ์ฌ์ฉํ ์ ์๋ค.
interface HasBothFunctionTypes {
property? : () => string; /* ์ ํ์ ์์ฑ */
method?() : string; /* ์ ํ์ ์์ฑ */
}
const hasBoth : HasBothFunctionTypes = {
property : () => "123",
method(){
return "";
}
};
console.log(hasBoth.property?.()); /* OK */
hasBoth.method?.(); /* OK */
ํจ์๋ฅผ ๋ถ๋ฌ์ค๋ ๋ถ๋ถ
console.log(hasBoth.property?.());
์ ๋ณด๋ฉด ์ ์ ์๋ฏ์ด ์ต์ ๋ ์ฒด์ด๋์ ํตํด ๊ฐ์ฒด์ ํจ์์ ์ ๊ทผํ ๋ชจ์ต์ด๋ค.
๋ง์ฝ ์๋์ ๊ฐ์ด ๋ถ๋ฌ์จ๋ค๋ฉด
console.log(hasBoth.property());
/*
Error: Cannot invoke an object which is possibly undefined
*/
์๋ฌ๋ฅผ ์ผ์ผํจ๋ค.
property๋ฅผ ํธ์ถํ ๋, TypeScript๋ ์ด ์์ฑ์ด undefined์ผ ๊ฐ๋ฅ์ฑ์ ์ธ์งํ๊ณ ๊ฒฝ๊ณ ๋ฅผ ๋ฐ์์ํจ๋ค.
๋ฐ๋ผ์ property์์ฑ์ด ์ต์ ๋ ์ฒด์ด๋์ ํตํด ๊ฐ์ด ์์๋๋ง ํธ์ถํ๋๋ก ๊ตฌํํ๋๊ฒ์ด ์ณ๋ค. (ํ์ ๊ฐ๋๋ ์ณ์ ๋ฐฉ๋ฒ์ด๋ค)
์ ์ธ : ๋ฉ์๋ vs ์์ฑ
- ๋ฉ์๋๋ readonly๋ก ์ ์ธํ ์ ์์ง๋ง ์์ฑ์ ๊ฐ๋ฅ
- ์ธํฐํ์ด์ค ๋ณํฉ์ ๋ฉ์๋์ ์์ฑ์ ๋ค๋ฅด๊ฒ ์ฒ๋ฆฌ
์คํ์ผ ๊ฐ์ด๋
- ๊ธฐ๋ณธ ํจ์๊ฐ this๋ฅผ ์ฐธ์กฐํ ์ ์๋ค๋ ๊ฒ์ ์๊ณ ์๋ค๋ฉด ๋ฉ์๋ ํจ์๋ฅผ ์ฌ์ฉํ๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ํด๋์ค์ ์ธ์คํด์ค์์ ์ฌ์ฉ๋จ
- ๋ฐ๋์ ๊ฒฝ์ฐ ์์ฑํจ์๋ฅผ ์ฌ์ฉํ๋ค.
2๏ธโฃ - 4. ํธ์ถ ์๊ทธ๋์ฒ
๐ํธ์ถ ์๊ทธ๋์ฒ๋ ํจ์๊ฐ ์ด๋ค ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๊ณ ์ด๋ค ํ์ ์ ๊ฐ์ ๋ฐํํ๋์ง๋ฅผ ์ ์ํ๋ ๊ฒ์ด๋ค.
ํธ์ถ ์๊ทธ๋์ฒ๊ฐ ์ ์ธํ ๋ฐฉ์์ผ๋ก ํธ์ถ๋๋ ๊ฐ๋ง ์ธํฐํ์ด์ค์ ํ ๋นํ ์ ์๋ค.
function add(x: number, y: number): number {
return x + y;
}
์ฌ๊ธฐ์์ ํธ์ถ ์๊ทธ๋์ฒ๋ (x : number, y: number) => number ์ด๋ค.
TypeScript์์๋ ์ด ํธ์ถ ์๊ทธ๋์ฒ๋ฅผ ํ์ ์ผ๋ก๋ ๋ง๋ค ์ ์๋ค. (์๋์ ์ฝ๋)
type FunctionAlias = (input:string) => number;
type FunctionAlias = (input:string) => number;
interface CallSignature {
(input:string) : number;
}
/* Type : (input:string) => number */
const typedFunctionAlias : FunctionAlias = (input) => input.length;
const typedCallSignature: FunctionAlias = (input:string) => input.length;
interface FunctionWithCount {
count: number;
() : void;
}
let hasCallCount: FunctionWithCount;
function keepsTrackOfCalls() {
keepsTrackOfCalls.count += 1
console.log(`I've been called ${keepsTrackOfCalls.count} times!`);
}
keepsTrackOfCalls.count = 0
hasCallCount = keepsTrackOfCalls; /* OK */
function doesNotHaveCount() {
console.log("No Idea");
}
hasCallCount = doesNotHaveCount()
/*Error: Type void is not assignable to type FunctionWithCount */
์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด interface:FunctionWithCount์ count ์์ฑ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ํจ์์ธ keepsTrackOfCalls๋ FunctionWithCount ํ์ ์ hasCallCount์ ํ ๋น๋ ์ ์๋ค.
ํ์ง๋ง doesNotHaveCount ํจ์๋ฅผ ๋ณด๋ฉด count์์ฑ์ ์ฐ์ง ์๊ณ ์๊ธฐ์ FunctionWithCount ํ์ ์ hasCallCount ์ ํ ๋นํ ์ ์๋ค.
interface FunctionWithCount {
count: number;
() : void;
}
let hasCallCount: FunctionWithCount;
function keepsTrackOfCalls() {
keepsTrackOfCalls.count += "!"
console.log(`I've been called ${keepsTrackOfCalls.count} times!`);
}
keepsTrackOfCalls.count = ""
hasCallCount = keepsTrackOfCalls;
/*
Error: Type typeof keepsTrackOfCalls is not assignable to type FunctionWithCount
Types of property count are incompatible.
Type string is not assignable to type number
*/
๋น์ฐํ๊ฒ๋ ์์ ์ฝ๋์ฒ๋ผ count์ ์ด๊ธฐํ๋ฅผ " " ๋ก ํ๋ค๋ฉด interface์ count:number์ ํ์ ์ด ๋ง์ง ์๊ธฐ ๋๋ฌธ์ ํ์ ์๋ฌ๋ฅผ ์ผ์ผํจ๋ค.
2๏ธโฃ - 5. ์ธ๋ฑ์ค ์๊ทธ๋์ฒ
์ธ๋ฑ์ค ์๊ทธ๋์ฒ๋ ์ธํฐํ์ด์ค์ key:value ๊ฐ๊ฐ์ ํ์ ์ ๋์ ์ผ๋ก ์ ์ํ๋ ๊ฒ์ด๋ค.
์๋์ ์ฝ๋๋ฅผ ๋ณด์.
interface TsPractice{
[key:string] : number;
}
์๋ก ์ ์ธํ ๊ฐ์ฒด์ ๋ชจ๋ ํค๋ string ํ์ ์ด์ด์ผํ๋ฉฐ value๋ numberํ์ ์ด์ด์ผํจ์ ๋ช ์ํ๊ณ ์๋ค.
interface TsPractice{
[key:string] : number;
}
const practice: TsPractice = {};
practice.apple = 0; /* OK */
practice.banana = 1; /* OK */
practice.cap = "Teket"; /* Error: Type string is not assignable to type number */
์ธ๋ฑ์ค ์๊ทธ๋์ฒ๋ ๊ฐ์ฒด์ ๊ฐ์ ํ ๋นํ ๋ ํธ๋ฆฌํ์ง๋ง ํ์ ์์ ์ฑ์ ์๋ฒฝํ๊ฒ ๋ณด์ฅํ์ง๋ ์๋๋ค.
interface DatesByName {
[i:string] : Date;
}
const publishDates : DatesByName = {
Frankenstein : new Date("1 January 1818")
}
console.log(publishDates.Frankenstein.toString()); /* OK */
publishDates.Beloved;
console.log(publishDates.Beloved.toString()); /* OK, But Runtime Error*/
์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด Beloved๋ key๋ก์ string์ผ์ง๋ง value๊ฐ undefined๋ค.
ํ์ง๋ง ํ์ ์คํฌ๋ฆฝํธ๋ Beloved๊ฐ ์ ์๋์ง ์์์์๋ ์ ์๋์๋ค๊ณ ์๊ฐํ๋๋ก ์์ธ๋ค.
๋ฐ๋ผ์ ํ์ ์์คํ ์์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ค..
key/value ์์ ์ ์ฅํ๋ ค๊ณ ํ๋๋ฐ ํค๋ฅผ ๋ฏธ๋ฆฌ ์ ์ ์๋ค๋ฉด Map์ ์ฌ์ฉํ๋ ํธ์ด ๋ ์์ ํ๋ค.
.get ๋ฉ์๋๋ ํญ์ ํค๊ฐ ์กด์ฌํ์ง ์์์ ๋ํ๋ด๊ธฐ ์ํด์ | undefined ํ์ ์ ๋ฐํํ๋ค.
์์ฑ๊ณผ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ ํผํฉ
์ธํฐํ์ด์ค๋ ๋ช ๋ช ๋ ์์ฑ๊ณผ ํฌ๊ด์ ์ธ ์ฉ๋์ string์ธ๋ฑ์ค ์๊ทธ๋์ฒ๋ฅผ ํ๋ฒ์ ํฌํจํ ์ ์๋ค.
interface Novels {
Oroonoko : number;
[i:string] : number;
}
/* OK */
const novels : Novels = {
Oroonoko : 1688,
Outlander : 1991,
}
const missingOroonoko : Novels = {
Outlander : 1991,
/*
Error: Property Oroonoko is missing in type { Outlander: number; } but required in type Novels
index.ts(2, 5): Oroonoko is declared here.
*/
}
๋ช ๋ช ๋ interface๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฒด๋ ๋ฐ๋์ ํด๋น ์์ฑ์ ํฌํจํด์ผํ๊ธฐ ๋๋ฌธ์ Oroonoko๋ฅผ ๋นผ๋จน์ ์์ ์ํฉ์ ํ์ฉ๋์ง ์๋๋ค.
๋ํ ๋ช ๋ช ๋ ์์ฑ์ ํ์ ์ด ์ธ๋ฑ์ค ์๊ทธ๋์ฒ์ ํ ๋น๋ ์ ์๋ ๊ฒฝ์ฐ TypeScript๋ ๋ ๊ตฌ์ฒด์ ์ธ ์์ฑ ํ์ ๋ฆฌํฐ๋ด์ ์ฌ์ฉํ๋ ๊ฒ์ ํ์ฉํ๋ค.
interface ChapterStarts {
preface : 0;
[i:string] : number;
}
const correctPreface :ChapterStarts = {
preface : 0,
night: 1,
shopping : 3
};
const wrongPreface :ChapterStarts = {
preface : 1
/*
Error: Type 1 is not assignable to type 0
*/
}
์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ
TypeScript์์ ๊ฐ์ฒด์ ํ๋กํผํฐ ํค๊ฐ ์ซ์์ผ ๋ ํด๋น ํค์ ๊ฐ์ ํ์ ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ๋ ์๋์ ๊ฐ์ด ์ ์๋๋ค.
interface NumberIndexedObject {
[key: number]: string;
}
const example: NumberIndexedObject = {
1: "One",
2: "Two",
100: "Hundred"
};
TypeScript์์๋ ์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ๊ฐ ๋ฌธ์์ด ์ธ๋ฑ์ค ์๊ทธ๋์ฒ์ ์๋ธํ์ ์ด์ด์ผ ํ๋ค๋ ๊ท์น์ด ์๋ค.
์๋ฅผ ๋ค์ด, arr[0]๊ณผ arr["0"]์ ๊ฐ์ ๊ฐ์ ์ฐธ์กฐํ๋ค.
/*
OK
*/
interface MoreNarrowNumbers{
[i:number] : string;
[i:string] : string | undefined;
}
/*
OK
*/
const mixesNumbersAndStrings : MoreNarrowNumbers = {
0 : '',
key1 : '',
key2: undefined
}
interface MoreNarrowStrings{
[i:number] : string | undefined;
/*
Error: number index type string | undefined
is not assignable to string index type string
*/
[i:string] : string;
}
๐ข ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ด์
interface MoreNarrowStrings {
[i: number]: string | undefined;
[i: string]: string;
}
์ฌ๊ธฐ์ ๋ฌธ์ ๊ฐ ๋๋ ๋ถ๋ถ์, ์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ์ ๊ฐ ํ์ ์ด string | undefined๋ผ๋ ์ ์ด๋ค.
TypeScript๋ ๋ชจ๋ ์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ๊ฐ ๋ฌธ์์ด ์ธ๋ฑ์ค ์๊ทธ๋์ฒ๋ก๋ ์ฌ์ฉ๋ ์ ์๋ค๊ณ ๊ฐ์ ํ๋ค.
๋ฐ๋ผ์, ์ด ๊ฒฝ์ฐ ์ซ์ ์ธ๋ฑ์ค ์๊ทธ๋์ฒ์ ๊ฐ ํ์ ์ ๋ฌธ์์ด ์ธ๋ฑ์ค ์๊ทธ๋์ฒ์ ๊ฐ ํ์ ์ธ string์ ์๋ธํ์ ์ด์ด์ผ ํ๋ค.
๊ทธ๋ฌ๋ string | undefined๋ string์ ์๋ธํ์ ์ด ์๋๊ณ .
์คํ๋ ค string ํ์ ์ด string | undefined์ ์๋ธํ์ ์ด๋ค. ์ด ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๊ฒ...
2๏ธโฃ - 6. ์ค์ฒฉ ์ธํฐํ์ด์ค
์ธํฐํ์ด์ค ํ์ ๋ ์์ฒด ์ธํฐํ์ด์ค ํ์ ํน์ ๊ฐ์ฒด ํ์ ์ ์์ฑ์ผ๋ก ๊ฐ์ง ์ ์๋ค.
interface Employee {
name: string;
age: number;
department: Department;
}
interface Department {
name: string;
roles: Role[];
}
interface Role {
title: string;
salary: number;
}
const employee: Employee = {
name: "Alice",
age: 30,
department: {
name: "Engineering",
roles: [
{
title: "Software Engineer",
salary: 70000
},
{
title: "Team Lead",
salary: 90000
}
]
}
};
console.log(employee);
'FrontEnd > Typescript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Typescript] ํด๋์ค(1) (2) | 2024.09.20 |
---|---|
[Typescript] ์ธํฐํ์ด์ค(2) (0) | 2024.08.19 |
[Typescript] ๋ฐฐ์ด(2) (0) | 2024.08.11 |
[Typescript] ๋ฐฐ์ด(1) (0) | 2024.08.05 |
[Typescript] ํจ์(2) (0) | 2024.03.06 |
์๋ ํ์ธ์? ๊ฐ๋ฐ์์ ๋๋ค.