๐ ์ด์ค ๋ฐ๋ณต๋ฌธ์์ ๋ฐ๋ณต๋ฌธ ์ํ ํ ํ์ ๊ฐ์ ํ๊ธฐ
์ธ๋ป ์ ๋ชฉ๋ง ๋ด์๋ ์ดํดํ๊ธฐ ํ๋ค ์ ์์ง๋ง, ์ฝ๊ฒ ๋งํด ํ์
์ด 2๊ฐ ์ด์์ธ data
์์ find
๋ฅผ ํตํด ๋์จ ๊ฐ์ ์ํ๋ property
๋ง ์ถ์ถํ๊ณ ์ถ์ ๋ ํด๋น ํ์
์ assertion
๋ฐฉ๋ฒ์ด๋ค. ์ด๋ฏธ data
์ ํ์
์ด ์ ํด์ ธ ์๋ ๊ฒฝ์ฐ๋ผ๋ฉด ๊ตณ์ด type assertion
ํด์ผ๋๋?๋ผ๊ณ ์๊ฐํ ์ ์์ง๋ง, API
์์ฒญ์ ํตํด ๋ฐ์ ๊ฐ(data
)์ ํ์
์ด 2๊ฐ ํน์ 2๊ฐ ์ด์์ผ๋ก ์ค์ ๋์ด์๊ณ , ๋ด๊ฐ ์ฌ์ฉํ๊ณ ์ถ์ property
๊ฐ ๊ฐ๊ฐ์ ํ์
์ ๊ณตํต์ผ๋ก ๋ค์ด์์ง ์์ property
์ธ๋ฐ, ํ์ชฝ ํ์
์ property
๋ง ์ถ์ถํ๋ฉด ์ปดํ์ผ ์๋ฌ๊ฐ ๋๋ ๊ฒฝ์ฐ ํด๊ฒฐ๋ฐฉ๋ฒ์ ๋ํด ๊ธ์ ์์ฑํ๋ค.
ํ ๊ฐ์ง ์์๋ฅผ ํตํด ์ดํด๋ณด์. API
๋ฅผ ํตํด ๋ฐ์ ๊ฐ data
๊ฐ์ด ์๊ณ , ๊ทธ data
์ ํ์
์ data[][]
์ด๋ค. ์ฌ๊ธฐ์ ๋ด๊ฐ ์ํ๋ ๋ก์ง์ find
๋ฉ์๋๋ฅผ ์ฌ์ฉํด type===info
์ value.text
๊ฐ์ ์ฐพ๊ณ type===info
์ value.text
์ ๊ฐ์ด ์์ผ๋ฉด Unknown
์ผ๋ก ์ ์ฅํ์ฌ ๊ฒฐ๊ตญ์ string []์
๋ฐํํ๋ ๋ก์ง์ ์์ฑํ๊ณ ์ถ๋ค.
๊ทธ๋ฐ๋ฐ, ํ๋จ ์ฝ๋ ๋ธ๋ก์ // Bad
์ฒ๋ผ ์์ฑํ๋ฉด ESlint
์์ Unsafe assignment ~
์๋ฌ๊ฐ ๋์ค๋ ๋ชจ์ต์ ๋ณผ ์ ์๋๋ฐ, ํ์
์คํฌ๋ฆฝํธ์์ dataDocument
์ ํ์
์ด ๋ช
ํํ์ง ์์ any[]
์ธ ํ์
์ผ๋ก ์ค์ ๋์ด ๋ํ๋๋ ์๋ฌ์๋ค. ๊ทธ๋์ as
๋ฅผ ์ฌ์ฉํด Not Good
์ฒ๋ผ ์์ฑํ์ผ๋, ์ด๋ฒ์ text
property
๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ ์๋ฌ์๋ค. as
๋ก ๊ฐ์ ํด์คฌ๋๋ฐ ์ ์ ๋ฐ ์๋ฌ๊ฐ ์๊ธฐ์ง..?๋ผ๊ณ ์๊ฐํ๋ฉฐ 30๋ถ์ ์ฝ์ง ๊ฒฐ๊ณผ ์ป์ ๊ฒ์ find
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ณ ๋์จ ๊ฒฐ๊ณผ์ ๋ํด ํ์
์ InfoType
์ผ๋ก ๊ฐ์ ํด์ค์ผ find
๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ณ ๋์จ ๊ฒฐ๊ณผ๋ ๋ชจ๋ InfoType
์ด๊ณ , InfoType
๋ด๋ถ์ ์๋ value.text
์ ์ ๊ทผ ํ ์ ์์์ ๊นจ๋ฌ์๋ค. ์ด์ ๋จ๊ณ์ assertion
์ ํด์ผํ๋ค๋ ์๊ฐํ์ง ๋ชปํ๊ณ ์ต์ข
๋จ๊ณ์ธ value.text
๊ฐ์ assertion
ํ์ฌ ์๊ธด ๋ฌธ์ ์์๋ค! Good
์ฒ๋ผ ์์ฑํ๋ฉด ์์ฐ์ค๋ฝ๊ฒ ์ต์
๋ ์ฒด์ด๋(?)์ ๋นผ๋ ๋๋ฏ๋ก ํ์ธต ๊ฐ๋
์ฑ์ด ๋์์ง ์ฝ๋๊ฐ ๋์๋ค. ๋์ ๊ฐ์ ๋ฌธ์ ๋ก ๊ณ ์ํ๋ ๋ถ๋ค์๊ฒ ๋์์ด ๋์์ผ๋ฉด ํ๋ ๋ฐ๋์ผ๋ก ๊ธ์ ๋ง์น๋ค.
22. 7. 5. ํ.typescript
์ ์ฌ์ฉ์-์ ์ ํ์
๊ฐ๋(User-Defined Type Guards)
์ธ is
ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ฑ ํ ์ ์๋ค. ์ฌ๊ธฐ์ ํ์
๊ฐ๋๋, ์ค์ฝํ ์์์์ ํ์
์ ๋ณด์ฅํ๋ ๋ฐํ์ ๊ฒ์ฌ๋ฅผ ์ํํ๋ค๋ ํํ์์ด๋ค. Use TypeGuard์ฝ๋์์ document is InfoType
์ฝ๋๋ฅผ ํตํด ํ์
์คํฌ๋ฆฝํธ๊ฐ document
์ ํ์
์ ๋ฒ์๋ฅผ InfoType
๋ก ์ถ์ ์ํฌ ์ ์๋ค. (ํผ๋๋ฐฑ ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค. ์ฐ๋๋ฐ๋ธ๋ :))
// type.ts
interface InfoType {
type: 'info'
value: {
text: string
}
}
interface ImageType {
type: 'images'
value: {
id: string
source?: object
}
}
type Data = InfoType | ImageType
// index.tsx
const data: Data[][] = [
[
{ type: "info", value: [Object] },
{ type: "images", value: [Object] },
],
[
{ type: "info", value: [Object] },
{ type: "images", value: [Object] },
],
[
{ type: "info", value: [Object] },
{ type: "images", value: [Object] },
],
[
{ type: "info", value: [Object] },
{ type: "images", value: [Object] },
],
];
// Bad
const infoTextLabels: string[] = data.map(
(dataDocument) =>
dataDocument.find(({ type }) => type === 'info')?.value.text ||
'Unknown',
)
// Not Bad
const infoTextLabels: string[] = data.map(
(dataDocument) =>
(dataDocument.find(({ type }) => type === 'info')?.value
.text as InfoType['value']['text']) || 'Unknown',
)
// Good
const infoTextLabels: string[] = data
.map(
(dataDocument) =>
(
dataDocument.find(
({ type }) => type === 'info',
) as InfoType
).value.text || 'Unknown',
)
// Use TypeGuard
const tabLabels = entries
.map(
(embeddedDocument) =>
embeddedDocument.find(
(document): document is InfoType =>
document.type === 'info',
)?.value.text || 'Unknown',
)
๋๊ธ