[TS] ํ์ ์คํฌ๋ฆฝํธ์ ๊ณต๋ณ์ฑ / ๋ฐ๊ณต๋ณ์ฑ / ์ด๋ณ์ฑ
TL;DR
์๊ฒฉ ๋ชจ๋ | ๋น์๊ฒฉ ๋ชจ๋ | |
ํจ์ ๋ฆฌํด ํ์ | ๊ณต๋ณ์ | ๊ณต๋ณ์ |
ํจ์ ํ๋ผ๋ฏธํฐ ํ์ | ๋ฐ๊ณต๋ณ์ | ์ด๋ณ์ |
๊ทธ ์ธ | ๊ณต๋ณ์ | ๊ณต๋ณ์ |
- ๊ณต๋ณ์ฑ : ์ํผ ํ์
(๋์ ํ์
)์ด ์๋ธ ํ์
(์ข์ ํ์
)์ ์ปค๋ฒํ๋ ๊ด๊ณ
- ์๋ธ ํ์
์ ์ํผ ํ์
์ ๋์
ํ ์ ์์ e.g.
superType = subType
- ํ์ ์คํฌ๋ฆฝํธ ๊ธฐ๋ณธ ๋์
- ์๋ธ ํ์
์ ์ํผ ํ์
์ ๋์
ํ ์ ์์ e.g.
- ๋ฐ๊ณต๋ณ์ฑ : ์๋ธ ํ์
(์ข์ ํ์
)์ด ์ํผ ํ์
(๋์ ํ์
)์ ์ปค๋ฒํ๋ ๊ด๊ณ
- ์ํผ ํ์
์ ์๋ธ ํ์
์ ๋์
ํ ์ ์์ e.g.
subType = superType
- ํจ์ ํ๋ผ๋ฏธํฐ ๋์
- ์ํผ ํ์
์ ์๋ธ ํ์
์ ๋์
ํ ์ ์์ e.g.
- ์ด๋ณ์ฑ : ๊ณต๋ณ์ฑ๊ณผ ๋ฐ๊ณต๋ณ์ฑ์ ๋ชจ๋ ํฌํจํ๋ ๊ด๊ณ
- ์ํผ ํ์ ๊ณผ ์๋ธ ํ์ ์ ๋ชจ๋ ๋์ ํ ์ ์์
strictFunctionTypes
์ต์ ์ ๊ป์ ๋ ํจ์ ํ๋ผ๋ฏธํฐ ๋์
๊ณต๋ณ์ฑ | Covariance
๊ณต๋ณ์ฑ :
A
๊ฐB
์ ์๋ธ ํ์ ์ด๋ฉด,T<A>
๋T<B>
์ ์๋ธ ํ์
์๋ ์์์์ superArray
(string | number
)๋ subArray
(string
)๋ณด๋ค ๋์ ํ์
์ ๊ฐ์ง๋ค. ๋ฐ๋ผ์ string
์ string | number
์ ํฌํจ๋๋ ์๋ธ ํ์
์ด๊ณ , string | number
๋ string
์ ํฌํจํ๋ ์ํผ ํ์
์ด๋ค.
์ข์ ํ์
์ธ subArray
๋ฅผ ๋์ ํ์
์ธ superArray
์ ๋์
ํ๋๊ฑด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค. ๋ฐ๋ฉด ๋์ ํ์
์ ์ข์ ํ์
์ ๋์
ํ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
// ๊ณต๋ณ์ฑ ์์
let superArray: Array<string | number> = [];
let subArray: Array<string> = [];
superArray = subArray; // OK
subArray = superArray; // Error 'number' ํ์์ 'string' ํ์์ ํ ๋นํ ์ ์์ต๋๋ค(ts2322)
์ด์ฒ๋ผ ์ข์ ํ์ ์ ๋์ ํ์ ์ ๋์ ํ ์ ์๋ ๋์์ ๊ณต๋ณ์ฑ(Covariance; ๅๆนๅทฎ)์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ํ์ ์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณต๋ณ์ฑ์ ๊ฐ๋๋ค.
ํจ์์ ๋ฆฌํด ํ์
์ญ์ ๊ณต๋ณ์ฑ์ ๊ฐ์ง๋ค. a
์ ๋ฆฌํด ํ์
(number
)์ด B
์ ๋ฆฌํด ํ์
(number | string
)๋ณด๋ค ์ข์ ํ์
์ด๋ฏ๋ก, a
๋ฅผ b
์ ๋์
ํด๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
// ํจ์ ๋ฆฌํด ํ์
์ ๊ณต๋ณ์ฑ — 1
function a(x: string): number { return 0; }
type B = (x: string) => number | string;
const b: B = a; // OK (a ๋ฆฌํด ํ์
< B ๋ฆฌํด ํ์
)
๋ฐ๋๋ก a
๋ฆฌํด ํ์
์ด ๋ ๋์ ํ์
์ ๊ฐ๋๋ก ๋ณ๊ฒฝํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
// ํจ์ ๋ฆฌํด ํ์
์ ๊ณต๋ณ์ฑ — 2
function a(x: string): number | string { return 0; }
type B = (x: string) => number;
const b: B = a; // Error (a ๋ฆฌํด ํ์
> B ๋ฆฌํด ํ์
)
๋ฐ๊ณต๋ณ์ฑ | Contravariance
๋ฐ๊ณต๋ณ์ฑ :
A
๊ฐB
์ ์๋ธ ํ์ ์ด๋ฉด,T<B>
๋T<A>
์ ์๋ธ ํ์
๋์ ํ์
์ ์ข์ ํ์
์ ๋์
ํ ์ ์๋ ๋์์ ๋ฐ๊ณต๋ณ์ฑ์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. ํ์
์คํฌ๋ฆฝํธ์์ ํจ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ฐ๊ณต๋ณ์ฑ์ ๊ฐ๋๋ค. — strictFunctionTypes
์ต์
์ ์ผฐ์ ๋
์๋ ์์์์ ๋์ ํ์
(์ํผ ํ์
)์ ๊ฐ์ง log
๋ฅผ ์ข์ ํ์
(์๋ธ ํ์
)์ ๊ฐ์ง logNumber
์ ๋์
ํด๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ค. number
(log
) ํ์
์ string | number
(logNumber
) ํ์
์ ์๋ธ ํ์
์ด์ง๋ง, ์คํ๋ ค Logger<string | number>
๊ฐ Logger<number>
์ ์๋ธ ํ์
์ผ๋ก ๋์ํ๊ณ ์๋ค. ์๋ธ ํ์
์ด ์ํผ ํ์
์ ์ปค๋ฒ ํ๋์
์ด๋ค.
// ํจ์ ํ๋ผ๋ฏธํฐ์ ๋ฐ๊ณต๋ณ์ฑ ์์1 - ์ฝ๋ ์ฐธ๊ณ via seob.dev
type Logger<T> = (param: T) => void;
let log: Logger<string | number> = (param) => { console.log(param); };
let logNumber: Logger<number> = (param) => { console.log(param); };
log = logNumber; // Error
logNumber = log; // OK
ํจ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ฐ๊ณต๋ณ์ฑ์ ๊ฐ๋ ์ด์ ๋ ์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ดํดํ๊ธฐ ์ฝ๋ค. Adder
ํ์
์ ๊ฐ๋ ํจ์์ ํ๋ผ๋ฏธํฐ๋ string
, number
ํ์
์ ์ฒ๋ฆฌํ ์ ์์ด์ผ ํ๋ค.
// ํจ์ ํ๋ผ๋ฏธํฐ์ ๋ฐ๊ณต๋ณ์ฑ ์์2 - ์ฝ๋ ์ฐธ๊ณ via seob.dev
type Adder = (a: string | number, b: string | number) => string | number;
let add: Adder;
add = (a: number, b: number) => { return a + b; }; // Error
๋ง์ฝ number
ํ์
๋ง ์ฒ๋ฆฌํ ์ ์๋ ํจ์๋ฅผ ํ ๋นํ๋ค๋ฉด string
ํ์
์ ์ฒ๋ฆฌํ ์ ์์ด์ Type-Safe ํ์ง ์๊ฒ ๋๋ค. ํจ์ ํ๋ผ๋ฏธํฐ๊ฐ ๋ฐ๊ณต๋ณ์ฑ์ ๊ฐ๋๊ฑด ์ด์ฐ๋ณด๋ฉด ๋น์ฐํ ๊ฒ์ฒ๋ผ ๋ณด์ธ๋ค.
๐ก ํจ์ ํ๋ผ๋ฏธํฐ๋ strictFunctionTypes
์ต์
์ ์ผฐ์ ๋(true
) ๋ฐ๊ณต๋ณ์ฑ์, ํด๋น ์ต์
์ ๊ป์ ๋(false
) ์ด๋ณ์ฑ์ ๊ฐ์ง๋ค. strictFunctionTypes
์ต์
์ ๊ธฐ๋ณธ๊ฐ์ true
์ด๋ค.
์ด๋ณ์ฑ | Bivariance
์ด๋ณ์ฑ :
A
๊ฐB
์ ์๋ธ ํ์ ์ผ ๋,T<A>
๋T<B>
์ ์๋ธ ํ์ ์ธ ๋์์ ์ํผ ํ์
--strictFunctionTypes
์ต์
์ ๋๋ฉด ํจ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ด๋ณ์ ์ผ๋ก ์๋ํ๋ค. ์ด๋ณ์ฑ์ ๊ณต๋ณ์ฑ๊ณผ ๋ฐ๊ณต๋ณ์ฑ์ ๋ชจ๋ ๊ฐ์ง๋ ๊ฒ์ ๋ปํ๋ค. ์ฆ, ํจ์ ํ๋ผ๋ฏธํฐ์ ์๋ธ ํ์
๊ณผ ์ํผ ํ์
์ ๋ชจ๋ ์ฌ์ฉํ ์ ์๋ค.
์๋ ์์ ์์ Logger<string | number | boolean>
, Logger<number>
๋๋ค Logger<string | number>
์ ์๋ธ ํ์
์ผ๋ก ๋์ํ๊ณ ์๋ค.
// ํจ์ ํ๋ผ๋ฏธํฐ์ ์ด๋ณ์ฑ ์์ - ์ฝ๋ ์ฐธ๊ณ via seob.dev
type Logger<T> = (param: T) => void;
let log: Logger<string | number> = (param) => { console.log(param); };
log = (param: string | number | boolean) => { console.log(param); }; // OK
log = (param: number) => { console.log(param); }; // OK
๋ฉ์๋ ํ์ ์ ์ ๋ฐฉ์์ ๋ฐ๋ฅธ ์ฐจ์ด์
๐ก Array ๊ฐ์ ๋ฉ์๋๊ฐ ๊ณต๋ณ์ ์ผ๋ก ๋์ํ๋๋ก ๋ง๋ค๊ธฐ ์ํด ์๋ ๊ฐ์ ์ฐจ์ด์ ์ ๋ ๊ฒ์ด๋ผ๊ณ ํจ (์ฐธ๊ณ )
๋ฉ์๋ ํ์ ์ ์ ์ํ๋ ๋ฐฉ์์ ํ๋กํผํฐ(property) ๋ฐฉ์๊ณผ ์ค์ฌ์ฐ๊ธฐ(shorthand) ๋ฐฉ์ 2๊ฐ์ง๊ฐ ์๋ค. ์ด ๋์ ์ผํ๋ณด๋ฉด ๊ฐ์ ๋ณด์ด์ง๋ง ๋ฏธ๋ฌํ ์ฐจ์ด๊ฐ ์๋ค. ํ๋กํผํฐ ๋ฐฉ์์ ๋ฐ๊ณต๋ณ์ ์ผ๋ก ์๋ํ๊ณ , ์ค์ฌ์ฐ๊ธฐ ๋ฐฉ์์ ์ด๋ณ์ ์ผ๋ก ์๋ํ๋ค.
interface State<T> {
set: (item: T) => void; // ํ๋กํผํฐ ๋ฐฉ์(๋ฐ๊ณต๋ณ์ )
}
interface State<T> {
set(item: T): void; // ์ค์ฌ์ฐ๊ธฐ ๋ฐฉ์(์ด๋ณ์ )
}
strictFunctionTypes
์ต์
์ด ์ผ์ ธ์๋ค๋ฉด ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ ๋ฐ๊ณต๋ณ์ ์ผ๋ก ์๋ํ๋ค. ์๋ ์ฝ๋์์ ์๋ธ ํ์
(number
)์ ์ํผ ํ์
(number | string
)์ ๋์
ํ๊ณ ์๋ค. set
๋ฉ์๋ ํ๋ผ๋ฏธํฐ๊ฐ string
ํ์
์ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
interface State<T> {
set: (item: T) => void; // ํ๋กํผํฐ ๋ฐฉ์
}
const state: State<number | string> = {
set(item: number) { /* ... */ }, // ๊ณต๋ณ์ฑ Error
};
๋ฉ์๋ ํ์ ์ ์๋ฅผ ์ค์ฌ์ฐ๊ธฐ ๋ฐฉ์์ผ๋ก ์์ ํ๋ฉด ๊ณต๋ณ์ ์ผ๋ก๋ ์๋ํด์ ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ค(์ด๋ณ์ ์ด ๋จ).
interface State<T> {
set(item: T): void; // ์ค์ฌ์ฐ๊ธฐ ๋ฐฉ์
}
const state: State<number | string> = {
set(item: number) { /* ... */ }, // ๊ณต๋ณ์ฑ OK
};
const state: State<number | string> = {
set(item: number | string | boolean) { /* ... */ }, // ๋ฐ๊ณต๋ณ์ฑ OK
};
๋ฒ์ธ | ํ์ ํฌํจ ๊ด๊ณ ํ๊ธฐ๋ฒ
A <: B
:A
๋B
์ ์๋ธ ํ์A -> B
: ํจ์ ํ๋ผ๋ฏธํฐ ํ์ ์A
, ๋ฐํ ํ์ ์B
๋ ํผ๋ฐ์ค
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[CS] ์ค๋ฒํค๋ / ํ๋ก์ธ์ค / ์ค๋ ๋ (1) | 2024.05.18 |
---|---|
[JS] ๋ฌธ์ฅ, ๋จ์ด, ์์๋ณ๋ก ๋ฌธ์์ด ๋ถ๋ฆฌํ๊ธฐ (0) | 2024.05.17 |
[React] ๋ฆฌ์กํธ์์ Rendering ๋ ๋๋ง์ด๋? (0) | 2024.05.16 |
[TS] TypeScript ํ์ ์คํฌ๋ฆฝํธ satisfies ์ฐ์ฐ์ (0) | 2024.05.16 |
[React/JS] Promise ํ๋ก๋ฏธ์ค๋ฅผ ํ์ฉํ UX ๊ฐ์ โ ํด ๋ฏธ๋ฃจ๊ธฐ (0) | 2024.05.16 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[CS] ์ค๋ฒํค๋ / ํ๋ก์ธ์ค / ์ค๋ ๋
[CS] ์ค๋ฒํค๋ / ํ๋ก์ธ์ค / ์ค๋ ๋
2024.05.18 -
[JS] ๋ฌธ์ฅ, ๋จ์ด, ์์๋ณ๋ก ๋ฌธ์์ด ๋ถ๋ฆฌํ๊ธฐ
[JS] ๋ฌธ์ฅ, ๋จ์ด, ์์๋ณ๋ก ๋ฌธ์์ด ๋ถ๋ฆฌํ๊ธฐ
2024.05.17 -
[React] ๋ฆฌ์กํธ์์ Rendering ๋ ๋๋ง์ด๋?
[React] ๋ฆฌ์กํธ์์ Rendering ๋ ๋๋ง์ด๋?
2024.05.16 -
[TS] TypeScript ํ์ ์คํฌ๋ฆฝํธ satisfies ์ฐ์ฐ์
[TS] TypeScript ํ์ ์คํฌ๋ฆฝํธ satisfies ์ฐ์ฐ์
2024.05.16