์ ํ์ ์ ์ํ ๋ |
๊ตฌ๋ถ๋ ์ฌ๋ฌ ์ซ์๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
type TTerminalColors = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
๊ฐ ์ซ์๋ฅผ ๋์ดํ๋ ๋์ ์ซ์ ์ ํ์ ๋ฒ์๋ก ์ง์ ํ ์ ์์ต๋๋ค.
type TTerminalColors = 0..15;
type TRgbColorComponent = 0..255;
type TUInt = 0..4294967295;
์๋ง ์ฌ์ฉ ..
์ ์ ๋ฐ ...
์๋ .
interface Math {
random(): 0...1
}
์ด ์์ด๋์ด๋ ๋ฌธ์๋ก ํ์ฅํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด "b".."d"
๋ "b" | "c" | "d"
์
๋๋ค. ๋ฌธ์ ์งํฉ์ ์ง์ ํ๋ ๊ฒ์ด ๋ ์ฌ์ธ ๊ฒ์
๋๋ค.
๋๋ ์ด๊ฒ์ด ํ์ฅ๋ ์ ์๊ณ Haskell ๋ฒ์์ ๊ฐ์ ๊ตฌ๋ฌธ๊ณผ ์๋ฏธ๋ฅผ ์ฌ์ฉํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
| ๊ตฌ๋ฌธ | ๋์๊ฐ๋ |
|----------------------------|---------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------------------|
| type U = (e1..e3)
| type U = \| e1 \| e1+1 \| e1+2 \| ...e3 \|
๋
ธ์กฐ๋ never
์ ๊ฒฝ์ฐ e1 > e3
|
| type U2 = (e1, e2..e3)
| type U2 = \| e1 \| e1+i \| e1+2i \| ...e3 \|
,
์ฌ๊ธฐ์ ์ฆ๋ถ i
์ e2-e1
์
๋๋ค.
์ฆ๋ถ์ด ์์์ด๊ฑฐ๋ 0์ด๋ฉด ๋ค์ ์์๊ฐ e3
๋ณด๋ค ํด ๋ ํฉ์งํฉ์ด ์ข
๋ฃ๋ฉ๋๋ค.
ํฉ์งํฉ์ never
๊ฒฝ์ฐ e1 > e3
์
๋๋ค.
์ฆ๋ถ์ด ์์์ด๋ฉด ๋ค์ ์์๊ฐ e3
๋ณด๋ค ์์ ๋ ํฉ์งํฉ์ด ์ข
๋ฃ๋ฉ๋๋ค.
ํฉ์งํฉ์ never
๊ฒฝ์ฐ e1 < e3
์
๋๋ค. |
@panuhorsmalahti "bb".."dd"
๋ฅผ ์ง์ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
@streamich
์ ์์๋ ..๋ฅผ ์ฌ์ฉํ๊ณ ๋ถ๋ ์์์ ์๋ ...๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ ๋ ์ด์ ๊ฐ์ ์ ์ ์ ํ์ ์์ฑํ๋ ์์ด๋์ด๋ฅผ ์ ๋ง ์ข์ํ์ง๋ง ๋ถ๋ ์์์ ๊ฐ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
@aluanhaddad ํ๋ฅ ๋งํ๊ธฐ:
type TProbability = 0.0...1.0;
@streamich ๊ทธ๋์ ๊ทธ ์ ํ์๋ ์ด๋ก ์ ์ผ๋ก ๊ฐ๋ฅํ ์ฃผ๋ฏผ ์๊ฐ ๋ฌดํ๋์ ๋๊น?
@aluanhaddad ์ค์ ๋ก IEEE ๋ถ๋ ์์์ ์์ ๋ฌดํ๊ณผ๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ์ต๋๋ค. ๋ด ๊ณ์ฐ์ ๋ฐ๋ฅด๋ฉด 1,065,353,217๋ช ์ ์ฃผ๋ฏผ์ด ์์ ๊ฒ์ ๋๋ค.
0.0...1.0
? JS๋ IEEE double, ์ฆ 53๋นํธ์ ๋์ ๋ฒ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๊ฒ์ด ์ง์๋๋ค๋ฉด ๋ฒ์๋ ์ผ๊ธ ์ ํ์ด์ด์ผ ํ๋ฉฐ, ์ด๋ฅผ ํฉ์งํฉ์ ์ ์ฉํ๋ ๊ฒ์ ๋นํ์ค์ ์ผ ๊ฒ์
๋๋ค.
@jcready๋ ์ฌ์ค์ด์ง๋ง @fatcerberus๊ฐ ์ง์ ํ๋ฏ์ด ์ด๋ฅผ ํตํฉ ์ ํ์ผ๋ก ์ธ์ํ๋ ๊ฒ์ ์์ฒญ๋๊ฒ ํ์ฅ๋ ๊ฒ์ ๋๋ค.
์ํ ๊ต์ฐจ๋ก ๋ฐฉ์์ผ๋ก ๋ด๊ฐ ์ป์ ๊ฒ์ ์ด์ฐ ๋ ์ฐ์ ์ ํ์ ๊ฐ๋ ์ ์ธ์ด์ ๋์ ํ๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๊ฒ์ ๋ ธ๋ ์กฐํฉ ์ ํ์ผ๋ก ๊นจ๋ซ๋ ๊ฒ์ ์์ฒญ๋๊ฒ ํ์ฅ ๋ ๊ฒ์ ๋๋ค.
@aluanhaddad ์, ํ์ง๋ง unsigned ์ ์ ๋ฅผ ๊ณต์ฉ์ฒด๋ก ์ง์ ํ๋ ๊ฒ์กฐ์ฐจ ๋งค์ฐ ๋น์๋๋ค.
type TUInt = 0..4294967295;
์ค๋๋ ์ ๊ณต์ฉ์ฒด ๊ตฌํ์ ์ด๋ ๊ฒ ํฐ ๊ณต์ฉ์ฒด๋ฅผ ๊ตฌํํ๋ ๋ฐ ์์ ํ ๋ถ์ ํฉํ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์๋ ๋ช ๊ฐ์ง ๊ฐ๋ ฅํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ํ์ํฉ๋๋ค. ์ด๋ฐ ๊ธ์ ์ฐ๋ฉด ์ด๋ค ์ผ์ด ๋ฒ์ด์ง๊น
type UInt = 0..4294967295;
var x: UInt = ......;
if (x !== 4) {
x;
}
Union ์ ํ 0 | 1 | 2 | 3 | 5 | 6 | 7 | ...
์ ์ธ์คํด์คํ์
๋๋ค.
์๋ง๋ ์ซ์ ๋ฆฌํฐ๋ด์ ๋ํด์๋ง ์๋ํ ์ ์์ต๋๋ค. ๋ฆฌํฐ๋ด์ด ์๋ ์ซ์ ๊ฐ์ ๋ฒ์์ ์๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋๊ธฐ ์ ์ ํฌ๊ฑฐ๋ ์์ ๋น๊ต๋ฅผ ํตํด ๋ช
์์ ์ผ๋ก ๊ตฌ์ฒดํ๋์ด์ผ ํฉ๋๋ค. ์ ์ ๋ฒ์์๋ ์ถ๊ฐ Number.isInteger()
๊ฒ์ฌ๋ ํ์ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค์ ๊ณต์ฉ์ฒด ์ ํ์ ์์ฑํ ํ์๊ฐ ์์ด์ง๋๋ค.
@RyanCavanaugh ๋นผ๊ธฐ ์ ํ? ๐
๋ถ์ ์ ํ, ๋ถ์ ์ ํ.
๋ฌธ์์ด ์ด์ธ์ ๋ชจ๋ ๊ฒ:
type NotAString = !string;
0์ ์ ์ธํ ๋ชจ๋ ์ซ์:
type NonZeroNumber = number & !0;
@streamich ๋บ์ ์ ํ์ #4183์์ ๋ค๋ฃน๋๋ค.
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๋งค๊ฐ๋ณ์๋ฅผ 0 ๋๋ ์์(๋ฐฐ์ด ์ธ๋ฑ์ค)๋ก ์ ๋ ฅํ๊ณ ์ถ์ต๋๋ค.
@RoyTinker ํ์คํ ์ด๊ฒ์ด
๋ฐฐ์ด์ ๋จ์ง ๊ฐ์ฒด์ด๊ณ ์ค๋ฆ์ฐจ์ ์ธ๋ฑ์ค๋ ๋จ์ง ๊ด๋ก์ผ ๋ฟ์
๋๋ค.
let a = [];
for (let i = 0; i > -10; i -= 1) {
a[i] = Math.random() * 10;
}
๋ฐ๋ผ์ ๊ถ๊ทน์ ์ผ๋ก ์ฌ์ ํ ๋์ผํ ๊ฒ์ฌ๋ฅผ ์ํํด์ผ ํฉ๋๋ค.
function withItem<T>(items: T[], index: number, f: (x: T) => void) {
if (items[index]) {
f(items[index]);
}
}
์ด, ๋ถ, ์, ์ผ, ์ ๋ฑ๊ณผ ๊ฐ์ ์ ํ์ ์ ์ํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
@Frikki ์ด๋ฌํ ๋จ์๋ ์์ผ๋ก ์์ฑํ๋ ๊ฒ์ด ์ค์ฉ์ ์ด๊ณ ์์ฒญ๋๊ฒ ์ด๋ ค์ธ ์ ๋๋ก ์ ํ๋ ๊ฐ๊ฒฉ์ ์์ต๋๋ค.
type Hour =
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12
| 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23;
@aluanhaddad ํ์ง๋ง ์๋ช ๋์ง ์์ ์ ์๋ ์์ต๋๋ค.
type UInt = 0..4294967295;
์, ๋ค์๊ณผ ๊ฐ์ ์ ํ์ ์ด๋ป์ต๋๊น?
type Factorial<N extends number> = N > 2 ? Factorial<N - 1> * N : N;
type F1 = Factorial<1>; // 1
type F2 = Factorial<2>; // 1 | 2
type F3 = Factorial<3>; // 1 | 2 | 6
type FN = Factorial<number>; // 1 | 2 | 6 | ...
@aleksey-bykov ์ฃผ์์ *
์ฐ์ฐ์ ์ฌ์ฉ:
type char = 0..255;
type word = char ** 2;
type int = word ** 2;
type bigint = int ** 2;
@streamich ๋นํธ ์๋ฅผ ๋ ๋ฐฐ๋ก ๋๋ฆฌ๋ ๊ฒ์ 2์ ๊ณฑ์ ์ ํด๋นํ์ง ์์ผ๋ฉฐ 2๋ฅผ ์ง์๋ก ํ๋ ์ง์์ ๋ ๋น์ทํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ํ์ ์ฌ๋ฆฌ๋ฉด ์ ๋์ง๋ง ์ธ์ฝ๋ฉ ๊ฐ๋ฅํ ์ซ์๋ ํฌํจ๋๋ฏ๋ก ์ฌ์ ํ ์ ํํ์ง ์์ต๋๋ค. ๋์ฒด๋ก ์ด๊ฒ์ ์ข์ ์ ์ ์ ๋ต์ด ์๋๋๋ค.
@streamich , ์ผ๋ถ ์๊ฒฌ:
char
, word
๋ฑ์ ์ฉ์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค. ๋ค๋ฅธ ์ธ์ด์ ์ฌ๋๋ค์ ์ ์ ์ ์์ ๋ฐํ์ ๋์์ ์ฐจ์ด๋ฅผ ์ธ์ํ์ง ๋ชปํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.์ ํ ์์คํ
ํ๋ง์ ์๋ฃํ๊ณ Ctrl + Shift + B
์ณค์ ๋ ์ ์ง ๋ฌธ์ ๋ฅผ ์ฆ๊ธฐ๋๋ก ํฉ์๋ค.
@aleksey-bykov ์ด ์ข์ ๋ฌธ์ ๋ฅผ ๊ผญ ๊ธฐ์ตํ๊ณ ๊ณ์ค ๊ฑฐ์์ ๐
@aluanhaddad
๊ทธ ๋จ์[์๊ฐ ๋จ์]๋ ์์ผ๋ก ์ฐ๋ ๊ฒ์ด ์ค์ฉ์ ์ด๊ณ ์์ฒญ๋๊ฒ ์ด๋ ค์ธ ์ ๋๋ก ์ ํ๋ ๊ฐ๊ฒฉ์ ์์ต๋๋ค.
https://github.com/Microsoft/TypeScript/issues/15480#issuecomment -349270853
์ด์ ๋ฐ๋ฆฌ์ด๋ก ๊ทธ๋ ๊ฒ ํ์ธ์. :wink:
์ด ๋ฌธ์ ๋ ์ฃฝ์์ต๋๊น?
@Palid [Needs Proposal]
ํ๊ทธ๊ฐ ๋ถ์ด์์ด์ ์์ฌ์ค๋ฝ์ต๋๋ค.
ํ ๋ก ์ด ์ฌ๋ฏธ์์์ง๋ง ์ฐ๋ฆฌ ๋๋ถ๋ถ์ ์ค๋๋ ฅ ์๋ ์ค์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ ๊ณตํ๋ ๋ฐ ์คํจํ์ต๋๋ค.
https://github.com/Microsoft/TypeScript/issues/15480#issuecomment -324152700 ์ฐธ์กฐ
__์ฌ์ฉ ์ฌ๋ก:__
TypeScript์ ํ์ ์งํฉ์ด WebAssembly ๋๋ ๋ค๋ฅธ ๋์์ผ๋ก ์ปดํ์ผ๋ ์ ์๋๋ก ์ ํํ int ์ ํ์ ์ ์ํ ์ ์์ต๋๋ค.
๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ UInt8Array
, Int8Array
, Uint16Array
๋ฑ์
๋๋ค. TypeScript์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฑฐ๋ ์ธ ๋ ์ค๋ฅ๊ฐ ์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
const ab = new ArrayBuffer(1e3);
const uint8 = new UInt8Array(ab);
uint8[0] = 0xFFFFFFFF; // TSError: Number too big!
๋ด OP์์ ๋ช ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ธ๊ธํ์ต๋๋ค.
์ด๊ฒ์ ๊ตฌํํ๋ฉด TypeScript ์ปค๋ฎค๋ํฐ์์ ์๋ฐฑ๋ง ๊ฐ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ ์ํ ๊ฒ์ ๋๋ค.
๋๋ ์ ๋ง๋ก ์ฌ๋ฏธ์๋ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ, ์ค์ ๋ก ์ฌ๊ธฐ์์ ์ ์๋ ๋ค๋ฅธ ๊ฒ์ ๋ ๊ฐ๊น์ธ ์ ์์ต๋๋ค.
API๋ ์ผ๋ถ ๋ฒ์(์ ๊ฒฝ์ฐ์๋ 5-30) ์ฌ์ด์ ์ ์๋ฅผ ์ฌ์ฉํ๋ฉฐ ์ด๋ฅผ ์ํ SDK๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
์๋์ ์๋์ผ๋ก ์์ฑํ๋ ๊ฒ์ 25๊ฐ ๊ฐ์ ๋ํด ์ง๋ฃจํ์ง๋ง(์ด๋ ์ ๋ ์๋ํ๋ ์ ์์), ์๋ฐฑ ๋๋ ์์ฒ์ ์ด๋ป์ต๋๊น?
type X = 5 | 6 | 7 | 8 | 9 | 10 ... | 30
@Palid ์ด ๊ธฐ๋ฅ์ ๋ํด ๋ด๊ฐ ๋ณธ ๊ฒ ์ค ๊ฐ์ฅ ๊ฐ๋จํ๊ณ ๊ฐ์ฅ ์ข์ ๊ฒฝ์ฐ์ ๋๋ค.
5..30
์ ๊ฐ์ ๋ฒ์๊ฐ 5 | 6 | 7 ... | 30
(๋๋ ์ด์ ๋์ผํ ๊ธฐ๋ฅ)์ ๋ํ ๊ตฌ๋ฌธ ์คํ์ผ๋ก ์ ์๋ ๊ฒฝ์ฐ ์ฝ๊ฒ ์น๋ฆฌํ ์ ์์ ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์์๋ ์ด์ฐ์ ์ธ ์ ์ ๋ฒ์๋ฅผ ๋ํ๋
๋๋ค.
์ฐ์ ๋ฒ์(๋ถ์ฐ์๊ณผ ๋ฐ๋)๋ ๋ง์นจํ๊ฐ ์๋ ์ซ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๊ธฐํ ์ ์์ต๋๋ค -- 5.0..30.0
.
๋๋ ์ค์ ๋ก ํ์ดํ ๋ณดํธ๋ฅผ ๊ตฌํํ๊ธฐ ์ํด Typescript๋ฅผ ์ดํด๋ณด๋ ๊ฒ์ ๊ณ ๋ คํ๊ณ ์์์ต๋๋ค.
https://www.npmjs.com/package/memory-efficient-object
๋ฒ์ ์ ๋ ฅ์ ์ฌ์ฉํ๋ฉด ์ ํ ๊ฒ์ฌ ์ ์ ์ฌ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ค๋ฒํ๋ก๋ฅผ ๋ ์ฝ๊ฒ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ๋ ํฉ์งํฉ ํ์ฅ์ด ์ค์ ๋ก ํ์ํ์ง ์์ง๋ง ๋ฒ์๋ฅผ ๋น๊ตํ๋ ํฌ๊ด์ /๋ฐฐํ์ ๋ฒ์ ์ ์์ ๋ ๊ฐ๊น์ต๋๋ค.
type TTerminalColors = int & [0,15];
// int && v >= 0 && v <= 15
์ด๊ฒ์ ์๋ ๋ฒ์๊ฐ 0-255์ธ ๋ชจํฐ(์: Johnny-Five ์ฌ์ฉ)๋ฅผ ์ ์ดํ ๋ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก: TypeScript๋ฅผ ์ฌ์ฉํ์ฌ Canvas ๊ธฐ๋ฐ ๊ทธ๋ฆฌ๊ธฐ ํ๋ก๊ทธ๋จ์ ๊ตฌํํ๊ณ ์์ผ๋ฉฐ ๋ถํฌ๋ช ๋(0.0์์ 1.0 ์ฌ์ด์ ์ซ์์ฌ์ผ ํจ)์ ๋ํ ์ ํ ๊ฒ์ฌ๋ฅผ ๋ฐ๊ณ ์ถ์ต๋๋ค.
์ด๊ฒ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ๋ ค๋ฉด ์ ๋ง ๋ชจ๋ ๊ฒ์ ์์์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
x <= 10
์ ๊ฐ์ ์กฐ๊ฑด์ ๋ํ ์ ํ ์ถ์string | number
๋ฒ์ ์ง์( x == 5
์ true
๋ํด x === "5"
true
์ด๋ฏ๋ก)int
์ ํ( number
์ ํ์ ์ ํ์ด ๋จ)์ ๋ํ ์ง์๊ณผ int
-only ๋ฐ string | int
๋ฒ์์ ๋ํ ์ง์๋ ์์ ๊ฒ์
๋๋ค. x|0
์ ๊ฐ์ ํํ์์ ๊ฒฝ์ฐ์๋ ์ถ์๋ฅผ ์
๋ ฅํ์ญ์์ค.์ข์ ์์ด๋์ด์ง๋ง ๋ค๋ฃจ๊ธฐ์๋ ๋๋ฌด ๋ง์ต๋๋ค!
๋ฐํ์ ์ ํ ๊ฐ๋๊ฐ ํ์ํ์ง ์์ ์๋ ์์ต๋๋ค. ๋์ ์ฐ๋ฆฌ๋ ์ปดํ์ผ ํ์ ๊ฐ๋๋ฅผ ๋๊น์ง ๋ง๋ค ์ ์์ต๋๋ค.
๋์ ์ ๊ตํ ๋ถ๊ธฐ ์์ธก์ด ํ์ํฉ๋๋ค.
๊ฐ์ ํ๋ค
type TTerminalColors = int & [0,15];
function A(color: TTerminalColors):void
{
}
A(15); // OK
var x = 15;
A(x); // OK
function B(value: int) : void
{
A(value); // ERROR!!!
if(value >= 0 && value <= 15)
A(value); // OK, because we check that it is in the range of TTerminalColors
}
function C(value: int) : void
{
if(value < 0)
value = 0;
if(value > 15)
value = 15;
A(value); // OK, because is clamped. But maybe too hard to implemented
}
function ClampInt(value: int): TTerminalColors
{
if(value >= 0 && value <= 15)
return value; // Same as B(int)
if(value > 15)
return 15;
return 0;
}
๋ด ์ฌ์ฉ ์ฌ๋ก:
export const ajax: (config: AjaxOptions) => void;
type Callback = Success | Error;
type Success = (data: any, statusText: string, xhr: XMLHttpRequest) => void;
type Error = (xhr: XMLHttpRequest, statusText: string) => void;
interface AjaxOptions {
// ...
statusCode: { [code: number]: Callback | Callback[] },
// ...
}
statusCode
์ต์
์ ํค๋ฅผ ์ ํํ ์ ์์ผ๋ฉด ์ปดํ์ผ ํ์์ ์ํ ์ฝ๋๊ฐ ์ฑ๊ณต ๋๋ ์ค๋ฅ ์ฝ๋์ ํด๋นํ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
interface AjaxOptions {
// ...
statusCode: {
200..300: Success,
400..600: Error
},
// ...
}
IMO ์ด๊ฒ์ ๋ถ๋ ์์์ ๊ณผ ์ ์๋ก ์ ํ๋์ด์ผ ํ๋ฉฐ ๊ณต์ฉ์ฒด๋ก ๊ตฌํ๋์ด์๋ ์ ๋๋ฉฐ ์คํ๋ ค ์๋ก์ด ๋ฒ์ ์ ํ์ผ๋ก ๊ตฌํ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ ํ ๊ฒ์ฌ๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ๋จํฉ๋๋ค.
if (val >= range.start && val < range.end) {
return match;
} else {
return no_match;
}
์ฐ๋ฆฌ๋ ์๋ง ๋ฃจ๋น์ ์ฑ
์์ ์์ ๊ฐ์ง๊ณ ์ฌ์ฉํ ์์๋ ..
ํฌ๊ด์ ์ธ ๋ฒ์ (๋ํ [start, stop]
)์ ...
๊ฐ ์๋ ํฌ๊ด์ ์ธ ๋ฒ์์ ๋ํด์๊ฒ ( [start, stop)
).
๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ ๋ค์์ ์ ๋ ฅํ์ฌ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ ์ฝ๋๋ฅผ ํ์ธํ๋ ๊ฒ์ ๋๋ค.
๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ ์๋/๊ฒฝ๋ ๊ฐ์ ์ ํ ํ์ธํ๋ ๊ฒ์ ๋๋ค.
์ด๊ฒ์ #8665์ ์ผ๋ฐ์ ์ธ ์ ํจ์ฑ ๊ฒ์ฌ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ฒ๋ฆฌ๋ ์ ์์ต๋๋ค(์ด๊ฒ์ด ์ค๋ณต์ผ๋ก ๋ซํ ์ด์ ๋ ํ์คํ์ง ์์).
type TTerminalColors (n: number) => Math.floor(n) == n && n >= 0 && n <= 15;
type TRgbColorComponent (n: number) => Math.floor(n) == n && n >= 0 && n <= 255;
type TUInt (n: number) => n >= 0 && n <= 0..4294967295;
๋๋ #4639๋ฅผ ์ฌ์ฉํ๊ณ ๋ถํธ ์๋ ์ ์ ์ ํ์ด uint
๋ก ์ ์๋๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
type TTerminalColors (n: uint) => n <= 15;
type TRgbColorComponent (n: uint) => n <= 255;
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ์ ์ญ ์ขํ์ ๋๋ค. ํน์ ๋ฒ์(-90~90 ๋ฐ -180~180)์๋ง ์ํ๋๋ก ์๋์ ๊ฒฝ๋๋ฅผ ์ ๋ ฅํ๊ณ ์ถ์ต๋๋ค.
ํธ์ง: ์๋์ ๊ฒฝ๋์๋ ์์ ๋ฒ์๊ฐ ์์ต๋๋ค.
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ํฌ๊ธฐ๊ฐ ๋งค๊ฐ๋ณ์์ธ ๊ณ ์ ํฌ๊ธฐ์ ๋ฐฐ์ด์ ๊ตฌํํ๋ ๊ฒ์ ๋๋ค.
์๋ฅผ ๋ค์ด ๊ธธ์ด๊ฐ 2์ธ ๋ฌธ์์ด ๋ฐฐ์ด์ ์ ํ์ ์ ์ํ๊ณ ์ถ์ต๋๋ค.
let d: FixedSizeArray<2, string>;
d = [ 'a', 'b' ]; // ok
d = [ 'a' ]; // type error
d = [ 'a', 'b', 'c' ]; // type error
d[0] = 'a1'; // ok
d[1] = 'b1'; // ok
d[2] = 'c1' // type error
ํ์ฌ ๋ฒ์ ์ TS๋ฅผ ์ฌ์ฉํ๋ฉด ์์ "์ฌ์"์ ๋งค์ฐ ๊ฐ๊น์ด ๊ฒ์ ์ ์ํ ์ ์์ต๋๋ค. ์ฃผ์ ๋ฌธ์ ๋ ๊ตฌ์ฑ์ ์ก์ธ์ค์
๋๋ค. ์๋ฅผ ๋ค์ด d[1] = 'b1'
๋ ์ฌ๋ฐ๋ฅธ ๊ฒฝ์ฐ์๋ ์ ํ ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค. ์ค๋ฅ๋ฅผ ํผํ๊ธฐ ์ํด ๋ชจ๋ ๋ฒ์ ์ธ๋ฑ์ค ๋ชฉ๋ก์ FixedSizeArray
์ ์์์ ์์ผ๋ก ์ปดํ์ผํด์ผ ํฉ๋๋ค. ์ด๋ ์ง๋ฃจํฉ๋๋ค.
range
์ฐ์ฐ์์ ์ ์ฌํ keyof
์ฐ์ฐ์๊ฐ ์๋ ๊ฒฝ์ฐ ๋ค์ ์ ํ ์ ์๊ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ผ ํฉ๋๋ค.
type FixedSizeArray<U extends number, T> = {
[k in range(U)]: T;
} & { length: U };
์ฌ๊ธฐ์ range(N)
๋ range(0,N)
์ ๋ฐ๋ก ๊ฐ๊ธฐ์
๋๋ค.
์ฃผ์ด์ง ์ซ์ ๋ฆฌํฐ๋ด(์์ฐ) M, N๊ณผ M < N,
type r = range(M, N);
์ ๋๋ฑํ๋ค
type r = M | M+1 | ... | N-1
๋ ์ผ๋ฐ์ ์ผ ์ ์๋ ๊ฒ์ ์ ์ด ๋๋ค๋ฅผ ์ ์ํ๊ณ ์ ํ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ด ์๋ค๋ ๊ฒ์ ๋๋ค. ์์:
predicate mypredicate = (x) => x > 1 && x < 10
let x: mypredicate = 11 // not ok
let x: mypredicate = 5 // ok
Lambda๊ฐ ์ด๋ฏธ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฏ๋ก ์ ๋ฌธ๊ฐ๋ ๊ตฌ๋ฌธ ๋ณต์ก์ฑ์ด ๋ฎ์ ๊ฒ์
๋๋ค. ์ฐ๋ฆฌ๊ฐ ํ์ํ ๊ฒ์ ์ ํ์ผ๋ก ์ฌ์ฉํ๋ ๊ธฐ๋ฅ๋ฟ์
๋๋ค. ์ ํ ๊ฒ์ฌ๋ ์ด์จ๋ ์ ํ ์คํฌ๋ฆฝํธ์ ๋ฐ๋ผ ๋ค๋ฆ
๋๋ค("Javascript์ ๋ํ ์์ ์งํฉ" ์ฒ ํ์ ์ผ๋์ ๋์ญ์์ค).
๋จ์ ์ ์ ์ด์ ๋ณต์ก์ฑ์ด ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ ๋๊ตฌ์ ์ฑ๋ฅ์ ๊ฒฐ์ ํ๋ค๋ ๊ฒ์
๋๋ค.
์ซ์/๋ฌธ์๊ฐ ์ฐ์ ์งํ์ ์ํ๋์ง ํ์ธํ๋ ๊ฒ์ ์ข์ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๊ฐ ๋ ์ ์์ต๋๋ค.
// a is the starting element d is the difference between two elements and L is the last element
const belongsToAP = (a, d, L) => {
return (x) => {
if(x < a || x > L) return false
let n = ((x-a)/d) + 1
if(Number.isInteger(n)) return true
return false
}
}
์ด๋ ๊ฒ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ ํ ๊ฒ์ฌ๋ฅผ ์ํํ ์ ์์ต๋๋ค.
์ ์ด includedToMyAP = includedToAP(1,1, 10)
let x : belongsToMyAP = 5 // ok
let y : belongsToMyAP = 7.2 // not ok
์ด๊ฒ์ ์บ๋ฆญํฐ๋ก๋ ํ์ฅ๋ ์ ์์ต๋๋ค.
@Kasah ์ด์ ์ ์ฌํ ๊ฒ์ด #
"API ๋ฐ์" ์ฌ์ฉ ์ฌ๋ก๋ก ๋ง์ ๊ฒ์ ๋์ก์ต๋๋ค. ๋ํผ ํจ์๋ฅผ โโ์์ฑ ์ค์ธ REST ๋์ ์ 1..1000 ๋ฒ์์ ์ ์๋ฅผ ์ธ์๋ก ์ฌ์ฉํฉ๋๋ค. ์ซ์๊ฐ ํด๋น ์ ์ฝ ์กฐ๊ฑด์ ์ถฉ์กฑํ์ง ์์ผ๋ฉด ์ค๋ฅ๊ฐ ์์ฑ๋ฉ๋๋ค.
๊ทธ๋์ ์ ๋ ์ซ์ ๋ฒ์์ ๋ํ ์ ์์ ์์ฑ ์ค์ด๋ฉฐ ์ด ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์ ๋ชจ๋ฅด๊ฒ ์ด์ ๊ณ ๋ ค๋ฅผ ์ํด ์ด ๋ฌธ์ ๋ฅผ ๋์ก์ต๋๋ค.
TypeScript ์ปดํ์ผ๋ฌ๋ TypeScript๋ก ์์ฑ๋์๊ธฐ ๋๋ฌธ์ ์ซ์ ์ฐ์ฐ์์ ์์ฑ์ ํ์ฉํ์ฌ ๋ฒ์ ์ ํ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
// Syntax: x..y for an inclusive integer range.
let x: 0..10 = randomNumber(0, 10);
let y = x + 2; // Can deduce that y: 2..12.
์ ๋ณ์์ ํ ๋นํ ๋๋ ๋ฌธ์ ๊ฐ ์์ง๋ง ๋์ฐ๋ณ์ด๋ ์ด๋ป์ต๋๊น?
let x: 0..10 = randomNumber(0, 10);
x += 2; // Error: 2..12 is not assignable to type 0..10 (upper bound is out of range).
์ด ์ค๋ฅ๋ ๊ธฐ์ ์ ์ผ๋ก ์ ํํ์ง๋ง ์ค์ ๋ก๋ ์ฒ๋ฆฌํ๊ธฐ๊ฐ ์์ฒญ๋๊ฒ ์ง์ฆ๋ ๊ฒ์ ๋๋ค. ๋ฒ์ ๋ฐํ ์ ํ์ผ๋ก ํจ์์์ ๋ฐํ๋ ๋ณ์๋ฅผ ๋ณ๊ฒฝํ๋ ค๋ฉด ํญ์ ์ ํ ์ฃผ์ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
let x = randomNumber(0, 10) as number; // If randomNumber doesn't return a type assigable to number
// this will be an error, but it would still be annoying to have to sprinkle "as number"
// expressions everywhere.
๊ทธ๋ฆฌ๊ณ ์ด๋ฅผ ๋ฌด์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ถ๊ฑด์ ํจ์ ์ป์ต๋๋ค.
function logNumber0To10 (n: 0..10): void {
console.log(n);
}
let x: 0..10 = randomNumber(0, 10);
x += 2; // Because we're ignoring mutations, x: 0..10, but the runtime value could be 11 or 12,
// which are outside the specified range...
logNumber0To10(x); // ...which means we lose type safety on this call.
์ด์ ๋ํ ์์ ์ ๋ณ์๊ฐ ์ ์ธ๋ ํ ๋ณ์์ ์ ํ์ ๋ณ๊ฒฝํ๋ ๊ธฐ๋ฅ์ด๋ฏ๋ก ์์ 2๋ x์ ์ ํ์ 2..12๋ก ๋ณ๊ฒฝํฉ๋๋ค. ํ์ง๋ง ๋ด ์ฒซ ๋ฒ์งธ ๋ณธ๋ฅ์ ์ปดํ์ผ๋ฌ์ ๋๋ฌด ๋ง์ ์ค๋ฒ ํค๋๋ฅผ ์๊ฐํ๋ ๊ฒ์ด ์ฌ์ฉ์์๊ฒ ํผ๋ ์ค๋ฌ์ธ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ํจ์์ ์ ๋ค๋ฆญ์ ์ด๋ป์ต๋๊น?
// How to define this return type, seeing as we can't do math in types?
function increment<L extends number, H extends number> (x: L..H): (L + 1)..(H + 1);
์์ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์๊ฐ์ด ์์ต๋๊น?
@JakeTunaley
๋์ฐ๋ณ์ด๋ ์ด๋ป์ต๋๊น?
๋์ฐ๋ณ์ด๊ฐ ๋ค๋ฅธ ํ ๋น๊ณผ ๋ค๋ฅธ ์ด์ ๋ ๋ฌด์์ ๋๊น?
๋ค์์ ์ ์์ ๋ํ ์ ์ ๊ฒธ์ํ ์๋์ ๋๋ค. ์ด ์ ์์ ๋ํ ๋ค๋ฅธ ์ ํ์ ์ถ๊ฐํ๋๋ก ์์ฒญํฉ๋๋ค.
Infinity
์ ํInfinity
๊ฐ๋ง ์์ต๋๋ค.-Infinity
์ ํ-Infinity
๊ฐ๋ง ์์ต๋๋ค.NaN
์ ํNaN
๊ฐ๋ง ์์ต๋๋ค.double
์ ํ[-Number.MAX_VALUE, Number.MAX_VALUE]
๋ฒ์์ ๋ชจ๋ number
๊ฐ ๋๋ [-1.7976931348623157e+308, 1.7976931348623157e+308]
number
๋ Infinity|-Infinity|NaN|double
int
์ ํdouble
์ ํ์ ์ ํ[Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER]
๋๋ [-9007199254740991, 9007199254740991]
๋ฐ Math.floor(x) === x
๋ฒ์์ ๋ชจ๋ number
๊ฐ x
Math.floor(x) === x
3
๋ฐ 3.0
๊ฐ์ int
์ ํ์ด ๋ฉ๋๋ค.1
, 3.141
, 45
double
๋๋ int
ํ์ ์ ํ์ผ ์ ์์ต๋๋ค.(>= x)
๋ก ํ์๋ "GtEq" ์ ํx
๋ ์ ํ ๋ฆฌํฐ๋ด, Infinity
๋๋ -Infinity
(<= x)
๋ก ํ์๋ "LtEq" ์ ํx
๋ ์ ํ ๋ฆฌํฐ๋ด, Infinity
๋๋ -Infinity
(> x)
๋ก ํ์๋ "Gt" ์ ํx
๋ ์ ํ ๋ฆฌํฐ๋ด, Infinity
๋๋ -Infinity
(< x)
๋ก ํ์๋ "Lt" ์ ํx
๋ ์ ํ ๋ฆฌํฐ๋ด, Infinity
๋๋ -Infinity
(>= x)
(>= Infinity) = Infinity
(>= -Infinity) = -Infinity|double|Infinity
Infinity
๋ (>= [finite-literal])
์ ํ์ ์ ํ์
๋๋ค.(>= [finite-literal])
๋ double|Infinity
์ ํ์ ์ ํ์
๋๋ค.(>= NaN) = never
(>= int) = (>= -9007199254740991)
(>= double) = (>= -1.7976931348623157e+308)
(>= number) = number
(> x)
(> Infinity) = never
(> -Infinity) = double|Infinity
Infinity
๋ (> [finite-literal])
์ ํ์ ์ ํ์
๋๋ค.(> [finite-literal])
๋ double|Infinity
์ ํ์ ์ ํ์
๋๋ค.(> NaN) = never
(> int) = (> -9007199254740991)
(> double) = (> -1.7976931348623157e+308)
(> number) = number
(<= x)
(<= Infinity) = -Infinity|double|Infinity
(<= -Infinity) = -Infinity
-Infinity
๋ (<= [finite-literal])
์ ํ์ ์ ํ์
๋๋ค.(<= [finite-literal])
๋ -Infinity|double
์ ํ์ ์ ํ์
๋๋ค.(<= NaN) = never
(<= int) = (<= 9007199254740991)
(<= double) = (<= 1.7976931348623157e+308)
(<= number) = number
(< x)
(< Infinity) = -Infinity|double
(< -Infinity) = never
-Infinity
๋ (< [finite-literal])
์ ํ์ ์ ํ์
๋๋ค.(< [finite-literal])
๋ -Infinity|double
์ ํ์ ์ ํ์
๋๋ค.(< NaN) = never
(< int) = (< 9007199254740991)
(< double) = (< 1.7976931348623157e+308)
(< number) = number
(>= Infinity)
, (> number)
๋ฑ๊ณผ ๊ฐ์ ๊ฒ์ ์์ฑํ ์ ์์ง๋ง,
๊ฒฐ๊ณผ ์ ํ์ด ๋ฒ์ ์ ํ์ด ์๋๋๋ค. ๊ทธ๋ค์ ๋ค๋ฅธ ์ ํ์ ๋ณ์นญ์ผ ๋ฟ์
๋๋ค.
๋ฒ์ ์ ํ์ ๋ค์ ์ค ํ๋์ ๋๋ค.
(>= [finite-literal])
(> [finite-literal])
(<= [finite-literal])
(< [finite-literal])
(> number)
์ ๊ฐ์ ๊ตฌ๋ฌธ์ ์ ๋ค๋ฆญ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ GtEq/Gt ์ ํ์ ํฉ์งํฉ์ ์ทจํ ๋ "๋ ๋ง์" ๊ฐ์ ๊ฐ์ง ์ ํ์ด ๊ฒฐ๊ณผ์ ๋๋ค.
(>= [finite-literal-A]) | (>= [finite-literal-B]) = ...
[finite-literal-A] >= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (>= [finite-literal-B])
(>= [finite-literal-A])
(>= 3) | (>= 5.5) = (>= 3)
(>= 3)
๋ (>= 5.5)
์ ์์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ (>= 3)
(>= 5.5)
(>= [finite-literal-A]) | (> [finite-literal-B]) = ...
[finite-literal-A] == [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (>= [finite-literal-A])
[finite-literal-A] > [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (> [finite-literal-B])
(>= [finite-literal-A])
(> [finite-literal-A]) | (> [finite-literal-B]) = ...
[finite-literal-A] >= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (> [finite-literal-B])
(> [finite-literal-A])
(> 3) | (> 5.5) = (> 3)
(> 3)
๊ฐ (> 5.5)
์ ์์ ์ ํ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.๋ํ,
(>= A|B) = (>= A) | (>= B)
(> A|B) = (> A) | (> B)
(> 4|3) = (> 4) | (> 3) = (> 3)
(> number|3) = (> number) | (> 3) = number | (> 3) = number
๋ LtEq/Lt ์ ํ์ ํฉ์งํฉ์ ์ทจํ ๋ "๋ ๋ง์" ๊ฐ์ ๊ฐ์ง ์ ํ์ด ๊ฒฐ๊ณผ์ ๋๋ค.
(<= [finite-literal-A]) | (<= [finite-literal-B]) = ...
[finite-literal-A] <= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (<= [finite-literal-B])
(<= [finite-literal-A])
(<= 3) | (<= 5.5) = (<= 5.5)
(<= 5.5)
๋ (<= 3)
์ ์์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ (<= 5.5)
(<= 3)
(<= [finite-literal-A]) | (< [finite-literal-B]) = ...
[finite-literal-A] == [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (<= [finite-literal-A])
[finite-literal-A] < [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (< [finite-literal-B])
(<= [finite-literal-A])
(< [finite-literal-A]) | (< [finite-literal-B]) = ...
[finite-literal-A] <= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (< [finite-literal-B])
(< [finite-literal-A])
(< 3) | (< 5.5) = (< 5.5)
(< 5.5)
๋ (< 3)
์ ์์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ (< 5.5)
(< 3)
๋ํ,
(<= A|B) = (<= A) | (<= B)
(< A|B) = (< A) | (< B)
(< 4|3) = (< 4) | (< 3) = (< 4)
(< number|3) = (< number) | (< 3) = number | (< 3) = number
๋ GtEq/Gt ์ ํ์ ๊ต์งํฉ์ ์ทจํ ๋ "๋ ์ ์" ๊ฐ์ ๊ฐ์ง ์ ํ์ด ๊ฒฐ๊ณผ์ ๋๋ค.
(>= [finite-literal-A]) & (>= [finite-literal-B]) = ...
[finite-literal-A] >= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (>= [finite-literal-A])
(>= [finite-literal-B])
(>= 3) & (>= 5.5) = (>= 5.5)
(>= 5.5)
๋ (>= 3)
์ ํ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ (>= 5.5)
(>= 3)
(>= [finite-literal-A]) & (> [finite-literal-B]) = ...
[finite-literal-A] == [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (> [finite-literal-B])
[finite-literal-A] > [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (>= [finite-literal-A])
(> [finite-literal-B])
(> [finite-literal-A]) & (> [finite-literal-B]) = ...
[finite-literal-A] >= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (> [finite-literal-A])
(> [finite-literal-B])
(> 3) & (> 5.5) = (> 5.5)
(> 5.5)
๋ (> 3)
์ ํ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ ๋ LtEq/Lt ์ ํ์ ๊ต์งํฉ์ ์ทจํ ๋ "๋ ์ ์" ๊ฐ์ ๊ฐ์ง ์ ํ์ด ๊ฒฐ๊ณผ์ ๋๋ค.
(<= [finite-literal-A]) & (<= [finite-literal-B]) = ...
[finite-literal-A] <= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (<= [finite-literal-A])
(<= [finite-literal-B])
(<= 3) & (<= 5.5) = (<= 3)
(<= 3)
๋ (<= 5.5)
์ ํ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ (<= 3)
(<= 5.5)
(<= [finite-literal-A]) & (< [finite-literal-B]) = ...
[finite-literal-A] == [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (< [finite-literal-B])
[finite-literal-A] < [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (<= [finite-literal-A])
(< [finite-literal-B])
(< [finite-literal-A]) & (< [finite-literal-B]) = ...
[finite-literal-A] <= [finite-literal-B]
์ด๋ฉด ๊ฒฐ๊ณผ๋ (< [finite-literal-A])
(< [finite-literal-B])
(< 3) & (< 5.5) = (< 3)
(< 3)
๋ (< 5.5)
์ ํ์ ์ ํ์ด๊ธฐ ๋๋ฌธ์ ์ ์๊ฐ MySQL UNSIGNED INT
๋ฐ์ดํฐ ์ ํ์ ๋ค์ด๊ฐ ์ ์๋๋ก ์ ์ ์ผ๋ก ํ์ธํ๋ ค๋ฉด,
//TODO Propose numeric and range sum/subtraction/multiplication/division/mod/exponentiation types?
function insertToDb (x : int & (>= 0) & (<= 4294967295)) {
//Insert to database
}
๋ฌธ์์ด์ด ์ฃผ์ด์ง ๊ธธ์ด์ธ์ง ์ ์ ์ผ๋ก ํ์ธํ๋ ค๋ฉด,
function foo (s : string & { length : int & (>= 1) & (<= 255) }) {
//Do something with this non-empty string that has up to 255 characters
}
๋ฐฐ์ด๊ณผ ์ ์ฌํ ๊ฐ์ฒด์ ์ ์ ํ length
๊ฐ์ด ์๋์ง ์ ์ ์ผ๋ก ํ์ธํ๋ ค๋ฉด,
function foo (arr : { length : int & (>= 0) }) {
//Do something with the array-like object
}
์ ํํ ์ซ์๋ง ์ฃผ์ด์ง๋๋ก ์ ์ ์ผ๋ก ๋ณด์ฅํ๊ธฐ ์ํด,
function foo (x : double) {
//`x` is NOT NaN|Infinity|-Infinity
}
๋ฐฐ์ด ์ธ๋ฑ์ค๊ฐ ์กด์ฌํ๋์ง ์ ์ ์ผ๋ก ํ์ธํ๋ ค๋ฉด?
function foo (arr : { [index : int & (>= 0) & (< 10)] : string }) {
console.log(arr[0]); //OK
console.log(arr[1]); //OK
console.log(arr[2]); //OK
console.log(arr[9]); //OK
console.log(arr[10]); //Error
}
์ซ์ ๋ฐ ๋ฒ์ ๋ํ๊ธฐ/๋นผ๊ธฐ/๊ณฑํ๊ธฐ/๋๋๊ธฐ/mod/์ง์ ์ ํ์ ์ ์ํ๊ณ ์ถ์ง๋ง ์ด ๋ฌธ์ ์์๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒ ๊ฐ์ต๋๋ค.
[ํธ์งํ๋ค]
double
์ด๋ฆ์ ๋ณ๊ฒฝํ๊ณ float
๋ผ๊ณ ๋ถ๋ฅผ ์ ์์ง๋ง double
๊ฐ ์ด๊ฒ์ด ๋ฐฐ์ ๋ฐ๋ ๋ถ๋ ์์์ ์ซ์์์ ๋ ์ ํํ๊ฒ ํํํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
[ํธ์งํ๋ค]
์ผ๋ถ ์ ํ์ never
.
์ปดํ์ผ๋ฌ๊ฐ ํ๋ฆ ๋ถ์์ ์ํํ๋๋ก ํ ์ ์์ต๋๊น?
์ด ๊ธฐ๋ฅ์ด ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
function DoSomething(x : int & (>= 0) & (< 10)){
// DoSomething
}
function WillError(x : int){
DoSomething(x); // error; x is not >= 0 & < 10
}
function WillNotError(x : int){
if(x >= 0 && x < 10)
DoSomething(x); // not error by flow analysis
}
ํ ๊ฐ์ง ๋ ์ฌ์ฉ ์ฌ๋ก: ๋ฐฑ๋ถ์จ์ ๋ํ๋ด๋ ํจ์์ ์ซ์ ์ ๋ ฅ์ด ์์ต๋๋ค. ๊ฐ์ 0๊ณผ 1 ์ฌ์ด๋ก ์ ํํ๊ณ ์ถ์ต๋๋ค.
๋ฐฉ๊ธ [...Array(256)].map((_,i) => i).join("|")
๋ฅผ ์คํํ์ฌ ๊ฐ์ฅ ๋ชป์๊ธด ์ ํ ์ ์๋ฅผ ๋ง๋ค์์ต๋๋ค.
์์ด ์๋ ์ ์์ ์์ ์ซ์๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
type ArrayT<T> = T extends (infer P)[] ? P : never;
type A = ArrayT<Range<5, 10>>;//5|6|7|8|9|10
๋ฒ์: https://github.com/kgtkr/typepark/blob/master/src/list.ts
"์์ ์ซ์"๋ 3๋จ๊ณ BigInt
๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์๋ฏธํฉ๋๊น?
@Mouvedia ์ปดํ์ผ๋ฌ์ ์ฌ๊ท ์ ํ์ ๋ง๋ ์ซ์
์ ์์๋ ..๋ฅผ ์ฌ์ฉํ๊ณ ๋ถ๋ ์์์ ์๋ ...๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
..
๋ ํฌํจ ๋ฒ์ ๋ฐ ...
์ ์ธ๋ฅผ ์๋ฏธํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด Ruby์์์ฒ๋ผ. http://rubylearning.com/satishtalim/ruby_ranges.html ์ฐธ์กฐ
์ ๋ ํฌ๊ด์ ์ธ ๋ฒ์์ ๋ฐฐํ์ ์ธ ๋ฒ์๋ฅผ ๊ตฌ๋ณํ๊ธฐ ์ํด ๋จ์ผ ๋ง์นจํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ํ์ง ์์ต๋๋ค.
๋ฐ์ด๋ค์ด๋ ๋ ๊น์? ์ ํ ์ง์ ์ ๋ํ ๋จ์ผ ํฅ์์ผ๋ก ๋ณด์ด๋ ์ด ๊ธฐ๋ฅ์ด ์ฌ๊ธฐ๋ก ๊ฐ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
type range = 1:2:Infinity // 1, 3, 5โฆ Infinity
์ด๊ฒ์ด ๋ง์ 4gl ํ๋ซํผ, ํนํ ํ๋ ฌ ์งํฅ ํ๋ซํผ์์ ์ซ์ ๋ฒ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ท ์ผํ ๋ฒ์๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ต์์ ๋ชจ๋ธ๋ง ์ ๊ทผ ๋ฐฉ์ ์ค ํ๋์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ์ํํฉ๋๋ค.
๋ฐ๋ผ์ ์์ฐจ ๋ฒ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
type decmials = 1:10 // like 1 .. 10 with all decimals in between
๊ทธ๋ฆฌ๊ณ ์ ์๋ง ์๋ค๋ฉด:
type integers = 1:1:10 // 1, 2, 3, 4, 5, 6, 7, 8, 10
// OR
type integers = number.integers<1:10>
๊ตฌ๋ฌธ์ ๊ฐ์ง๊ณ ๋๊ณ ์ถ๋ค๋ฉด:
type something = 1::10 // whatever use cases need today
๊ทธ๊ฒ์ด ํ ํฌ๋์ด์ ์นํ์ ์ด์ง ์๋ค๋ฉด, ์ ์๊ฐ์๋ ์ฌ๊ธฐ์์ ์ง์คํ ์ฌ๋ฐ๋ฅธ ์ฐจ๋จ ์ฐ์ ์์๊ฐ ์๋๋๋ค. ๋๋ ํ๋์ ์๋ฃจ์ ์ด ๋ค์ ์๋ฃจ์ ์ผ๋ก ๋์ด๊ฐ๋ ๋ฐ ์ ํ์ ๋์ง ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉด์ ์ด๊ฒ์ ์ง์ ํฉ๋๋ค.
ํธ์ง : ๋ด๊ฐ ์ค๋ช ํ์ง ๋ชปํ๋ ๊ฒ์ ํฌ๊ด์ฑ ์ธก๋ฉด์ ๋๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ์ฌ๋๋ค์ด ๋ชจ๋ ์ซ์๋ฅผ ์์์ ์ผ๋ก ํฌํจํ๋ ๊ท ์ผํ ๋ฒ์์ ์์กดํ์ฌ ๊ทธ๋ ๊ฒ ๋ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ ๊ทธ๊ฒ์ด ๋ฌธ์ ๊ฐ ๋์ง ์์ ์ด์ ๋ฅผ ์ดํดํ๊ธฐ ์ํด ์ถฉ๋ถํ ์ค์ฌ๋ฅผ ํ๊ณ ์๋์ง ๊ถ๊ธํด์ผ ํฉ๋๋ค. ์ฆ๊ฐ๊ฐ ๋ฒ์์ ๋๊ณผ ์ ํํ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ .
๋ฒ์ ์ ํ์์ "๋จ๊ณ" ํฌ๊ธฐ๋ฅผ ์ ์ํ ์ ์๋ค๋ ์ฌ์ค์ด ํฅ๋ฏธ๋กญ์ต๋๋ค.
"๋ถ๋ ์์์ "(๊ณ ์ ๋จ๊ณ ํฌ๊ธฐ ์์) ๋ฐ "์ ์"(1์ ๋จ๊ณ ํฌ๊ธฐ, ์ ์์์ ์์) ๋ฒ์ ์ธ์ ๋ค๋ฅธ ๋จ๊ณ ํฌ๊ธฐ์ ๋ฒ์์ ๋ํ ์ค์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ณธ ์ ์ด ์์ต๋๋ค.
๊ทธ๋์, ๊ทธ๊ฒ์ด ๋ค๋ฅธ ๊ณณ์์ ์ผ์ด๋ผ๋ ์์์ ๋ฃ๋ ๊ฒ์ ํฅ๋ฏธ๋กญ์ต๋๋ค. ์ด์ 4gl์ ๋ํด ๋ค์ด๋ณธ ์ ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฐฐ์์ผ ํฉ๋๋ค.
๋ฐ๊ฐ๋ฐฉ ๊ฐ๊ฒฉ์ ์ ์ํ ์ ์๋ ๊ฒ์ ๋ฐฐ์ด๊ณผ ์ ์ฌํ ๊ฐ์ฒด์ ์ ์ฉํฉ๋๋ค. ๊ฐ์ ๊ฒ,
interface SaferArray<T, LengthT extends integer & (>= 0)> {
length : LengthT;
[index in integer & (>= 0) & (< LengthT)] : T
}
ํฌ๊ด์ ์ธ ๋ฒ์๋ง ์์ผ๋ฉด (<= LengthT - 1)
ํ์ง๋ง ๋ ์ฐ์ํฉ๋๋ค.
๋ฐ์ด๋ค์ด๋ ๋ ๊น์? ์ ํ ์ง์ ์ ๋ํ ๋จ์ผ ํฅ์์ผ๋ก ๋ณด์ด๋ ์ด ๊ธฐ๋ฅ์ด ์ฌ๊ธฐ๋ก ๊ฐ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
type range = 1:2:Infinity // 1, 3, 5โฆ Infinity
์ด๊ฒ์ด ๋ง์ 4gl ํ๋ซํผ, ํนํ ํ๋ ฌ ์งํฅ ํ๋ซํผ์์ ์ซ์ ๋ฒ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
๊ท ์ผํ ๋ฒ์๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ต์์ ๋ชจ๋ธ๋ง ์ ๊ทผ ๋ฐฉ์ ์ค ํ๋์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ์ํํฉ๋๋ค.
๋ฐ๋ผ์ ์์ฐจ ๋ฒ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
type decmials = 1:10 // like 1 .. 10 with all decimals in between
๊ทธ๋ฆฌ๊ณ ์ ์๋ง ์๋ค๋ฉด:
type integers = 1:1:10 // 1, 2, 3, 4, 5, 6, 7, 8, 10 // OR type integers = number.integers<1:10>
๊ตฌ๋ฌธ์ ๊ฐ์ง๊ณ ๋๊ณ ์ถ๋ค๋ฉด:
type something = 1::10 // whatever use cases need today
๊ทธ๊ฒ์ด ํ ํฌ๋์ด์ ์นํ์ ์ด์ง ์๋ค๋ฉด, ์ ์๊ฐ์๋ ์ฌ๊ธฐ์์ ์ง์คํ ์ฌ๋ฐ๋ฅธ ์ฐจ๋จ ์ฐ์ ์์๊ฐ ์๋๋๋ค. ๋๋ ํ๋์ ์๋ฃจ์ ์ด ๋ค์ ์๋ฃจ์ ์ผ๋ก ๋์ด๊ฐ๋ ๋ฐ ์ ํ์ ๋์ง ์๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉด์ ์ด๊ฒ์ ์ง์ ํฉ๋๋ค.
ํธ์ง : ๋ด๊ฐ ์ค๋ช ํ์ง ๋ชปํ๋ ๊ฒ์ ํฌ๊ด์ฑ ์ธก๋ฉด์ ๋๋ค. ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ์ฌ๋๋ค์ด ๋ชจ๋ ์ซ์๋ฅผ ์์์ ์ผ๋ก ํฌํจํ๋ ๊ท ์ผํ ๋ฒ์์ ์์กดํ์ฌ ๊ทธ๋ ๊ฒ ๋ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ ๊ทธ๊ฒ์ด ๋ฌธ์ ๊ฐ ๋์ง ์์ ์ด์ ๋ฅผ ์ดํดํ๊ธฐ ์ํด ์ถฉ๋ถํ ์ค์ฌ๋ฅผ ํ๊ณ ์๋์ง ๊ถ๊ธํด์ผ ํฉ๋๋ค. ์ฆ๊ฐ๊ฐ ๋ฒ์์ ๋๊ณผ ์ ํํ ์ผ์นํ์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ธํ๊ณ .
ํ Haskell์์ ์ฒ๋ฆฌ๋๋ ๋ฐฉ์์ฒ๋ผ ๋ณด์ ๋๋ค. ๋๋ ์ด๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํ๋ค. ์์ฑ๊ธฐ๋ ์ง์ฐ ํ๊ฐ๋ ํ์ฉํฉ๋๋ค.
๋ค๋ฅธ ๊ตฌ๋ฌธ์ผ๋ก ๊ฒ์ผ๋ฅธ ํ๊ฐ๋ฅผ ํ ์ ์๋ ๊ฒ๊ณผ๋ ๋ค๋ฆ ๋๋ค =x
๋ฒ์ ์ ํ์์ "๋จ๊ณ" ํฌ๊ธฐ๋ฅผ ์ ์ํ ์ ์๋ค๋ ์ฌ์ค์ด ํฅ๋ฏธ๋กญ์ต๋๋ค.
๋ฒ์๋ฅผ ์์, ๋ ๋ฐ ์ฆ๊ฐ๋ก ์๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ฆ๋ถ์ด ์ ํํ ๋๊น์ง ๋ฐ์ฌ๋ฆผ๋๋ฉด ํฌํจ๋ฉ๋๋ค. ๋ฒ์ ํจ์๋ก ๋ฐฐ์ด ์ธ๋ฑ์ค์ ๊ธธ์ด๋ ๋ฐฐ์ด์ด ๋ ์ ์์ต๋๋ค. 0:1:9์๋ 10๊ฐ์ ์ธ๋ฑ์ค ๋จ๊ณ(๊ธธ์ด)๊ฐ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ฌ๊ธฐ์ ๋ฒ์๋ ๋ ํํ์์ ๊ฒฐํฉํ์ฌ ๋ ์ฝ๊ฒ ์ถ๋ก ํ ์ ์๋ ์ ํ ์์คํ
์ ๊ฒฝ์ฐ ํธ๋ฆฌํ๊ฒ integer & 0:9
์ ์์ต๋๋ค.
4GL์ ์ค์ ๋ก ์ผ๋ฐ์ ์ธ ๋ ์ด๋ธ์ ๋๋ค. ์ ์๊ฒ๋ ๋๋ถ๋ถ MatLab์ด์์ต๋๋ค.
๋ด ์์ ์ ํฌ๊ด์ ์ธ ๋ฒ์๋ง ์์ผ๋ฉด ์ ๋ค๋ฆญ์์ ์ฌ์ฉํ๊ธฐ๊ฐ ๋ ์ด๋ ค์์ง๋ค๋ ๊ฒ์ ๋๋ค(hack-y ์ ํ ์์ค ์ํ ์ฐ์ฐ์ ๊ตฌํํ์ง ์๋ ํ).
์ ํ ๋งค๊ฐ๋ณ์๋ก "๊ธธ์ด"๋ง ์ฌ์ฉํ๋ ๋์ ์ด์ ๊ธธ์ด์ ์ต๋ ์์ธ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ต๋ ์ธ๋ฑ์ค๋ ๊ธธ์ด-1๊ณผ ๊ฐ์์ผ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์ ๋งํ์ง๋ง, hack-y ์ ํ ์์ค์ ์ํ ์ฐ์ฐ์ ๊ตฌํํ์ง ์๋ ํ ์ค์ ๋ก ๊ทธ๋ฐ ๊ฒฝ์ฐ์ธ์ง ํ์ธํ ์ ์์ต๋๋ค.
@AnyhowStep ๊ทํ์ ์ฐ๋ ค ์ฌํญ์ ์ค๋ช ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ์๊ฐํ๊ณ ์์์ง๋ง ๋จผ์ ๋ค์์ ๋ช ํํ ํ๋ ๊ฒ์ด ๋์์ด ๋ ์ ์์ต๋๋ค.
(์ด ์ธ๋ฑ์ค/๊ฐ์ ์๋๋ฆฌ์ค์ ๊ฐ์) n-1 ๋ฌธ์ ์ ํน๋ณํ ์ ์ฉํ ์ ์๋ ํฌ๊ด ์ฌ๋ถ๋ฅผ ์ ์ณ๋๊ณ , ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ๋ ๋ ๋ฆฝ์ ์ผ๋ก ํด๊ฒฐ๋์๋ค๊ณ ๊ฐ์ ํ๋ฉด(๊ทธ๋ฅ ์ ๋จธ๋ฌ์คํ๊ฒ ์๊ฐํจ), ์ซ์ ๋ฒ์๊ฐ ์ ์ฉ๋๋ ๋ค๋ฅธ ์๋๋ฆฌ์ค๊ฐ ์์ต๋๊น? ์ ์ ํ๊ฒ ์ค๋ช ํ๊ธฐ ์ํด ์ฌ์ ํ ๋ ์ ์ธ์ ์ด๊ฑฐ๋ ๋น๊ด์ต์ ์ธ ๊ตฌ๋ฌธ์ด ํ์ํฉ๋๊น?
๋๋ ๋ ๊ฐ์ง ๋ณ๊ฐ์ ์ธก๋ฉด์ด ์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํด๋น ๋๋ฉ์ธ์ ๊ธฐ๋์น์ ์ผ์นํ๋ ์ซ์ ๋ฒ์๊ฐ ํ์ํ๊ณ ์ธ๋ฑ์ค/์นด์ดํธ ์ ํ์ ๋ํ ์ ์ด๋ ํ์ํฉ๋๋ค.
์์๋ง.
declare let x : (> 0);
x = 0.1; //OK
x = 0.0001; //OK
x = 0.00000001; //OK
x = 0; //Error
x = 1; //OK
x = -1; //Error
์ธํด๋ฃจ์๋ธ ์ ์ฉ ๋ฒ์๋ฅผ ์ฌ์ฉํ๋ฉด
declare let x : epsilon:epsilon:Infinity; //Where epsilon is some super-small non-zero, positive number
Infinity
์ ์ธํ ์์
declare let x : (> 0) & (< Infinity);
์ธํด๋ฃจ์๋ธ ์ ์ฉ ๋ฒ์๋ฅผ ์ฌ์ฉํ๋ฉด
const MAX_FLOAT : 1.7976931348623157e+308 = 1.7976931348623157e+308;
declare let x : epsilon:epsilon:MAX_FLOAT;
๋ํ ํ์ฌ ๋ ผ์์ ๊ด๋ จ์ด ์์ง๋ง ์ฌ๊ธฐ์ ์ซ์ ๋ฒ์ ์ ํ์ด ํ์ํ ๋ ๋ค๋ฅธ ์ด์ ๊ฐ ์์ต๋๋ค.
๋ด ํ๋ฃจ ์ผ๊ณผ์ ๋๋ถ๋ถ์ ์๋ก ๋ค๋ฅธ ์ํํธ์จ์ด ์์คํ ์ ํจ๊ป ์ฎ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ๋ง์ ์์คํ ์ ๋์ผํ ์๋ฏธ๋ฅผ ๊ฐ์ง ๋ฐ์ดํฐ์ ๋ํด ์๋ก ๋ค๋ฅธ ์๊ตฌ ์ฌํญ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
์: (systemA, 1์์ 255 ์ฌ์ด์ ๊ฐ), (systemB, 3์์ 73 ์ฌ์ด์ ๊ฐ) ๋ฑ
์: (systemC. ๋ฌธ์์ด ๊ธธ์ด 7-88), (systemD, ๋ฌธ์์ด ๊ธธ์ด 9-99), (systemE, ๋ฌธ์์ด ๊ธธ์ด 2-101) ๋ฑ
์ง๊ธ ๋น์ฅ์ ์ด๋ฌํ ๋ชจ๋ ๊ฐ๋ณ ์๊ตฌ ์ฌํญ์ ์ฃผ์ ๊น๊ฒ ๋ฌธ์ํํ๊ณ ํ ์์คํ ์ ๋ฐ์ดํฐ๊ฐ ๋ค๋ฅธ ์์คํ ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋งคํ๋ ์ ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ๋งคํ๋์ง ์์ผ๋ฉด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํฉ๋๋ค.
๋๋ ์ธ๊ฐ์ผ ๋ฟ์ด๋ค. ๋๋ ์ค์๋ฅผ ํ๋ค. ๋ฐ์ดํฐ๋ฅผ ๋งคํํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋ฒ์ ํ์ธ์ ์คํจํ์ต๋๋ค.
์ซ์ ๋ฒ์ ์ ํ์ ์ฌ์ฉํ๋ฉด ๋ง์ง๋ง์ผ๋ก ๊ฐ ์์คํ ์ด ์์ํ๋ ๋ฒ์๋ฅผ ์ ์ธํ๊ณ ์ปดํ์ผ๋ฌ๊ฐ ํ์ธํ๋๋ก ํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ๋ด๊ฐ ์ฌ์ฉํ๊ณ ์๋ API์ ๋ชจ๋ ๋ฌธ์์ด ๊ฐ์ ๋ํด 10k ๋ฌธ์์ด ๊ธธ์ด ์ ํ์ด ์๋ ์ํฉ์ด ์์์ต๋๋ค. ๊ธ์์, API๋ก ๊ฐ๋ ๋ชจ๋ ๋ฌธ์์ด์ด <= 10k ๋ฌธ์์ด ๊ธธ์ด์ธ์ง ํ์ธํ๋๋ก TypeScript์ ์ง์ํ ๋ฐฉ๋ฒ์ด ์์์ต๋๋ค.
TS๊ฐ ๊ฐ ์ ์๋ ๋ฉ์ง ์ปดํ์ผ ์ค๋ฅ ๋์ ๋ฐํ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
`string` is not assignable to `string & { length : (<= 10000) }`
@AnyhowStep "Range as Number type"์ด๋ผ๋ ๊ฒ์ด ๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ์(์ฆ, ๋ฒ์๊ฐ ๊ฐ๊ฒฉ๋ณด๋ค ํฌ๊ด์ฑ์ ๊ฐ์กฐํ๋ ์ด์ ๋ฅผ ๊ถ๊ธํดํ๋ TS๋ก ์ด๋ํ๋ ์ฌ๋)์ ๋ํ ์ผ๋ฐ์ ์ธ ๊ธฐ๋์ ๋จ์ํ ์ผ์นํ๋์ง ํ์ธํ๋ ๊ฒ์ด ์ ์๋๋ผ๋ ์ ์
์์งํ ์ฌ์ฉ ์ฌ๋ก๋ ํญ์ ๊ธฐ๋ฅ์ ๊ตฌ๋ํด์ผ ํ๋ฉฐ ์ธ๋ฑ์ค ๋ฐ ๊ธธ์ด์ ๊ด๋ จ๋ ๋ฌธ์ ๋ ์ฐ๋ฆฌ ์ค ๋ง์ ์ฌ๋๋ค์ด ๊ฐ๋ ์ ๋ง ๋์น๋ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ๋ผ์ ์ฌ๋ฐ๋ฅธ ๋ ์ด๋ธ ๋ฐ๋ก ์๋์์ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ถ์ต๋๋ค. ์ซ์ ์ ํ์ ๋๊น ์๋๋ฉด ์ธ๋ฑ์ฑ๋ ์ ํ์ ๋๊น? ๋๋ ๊ทธ ๋ต์ ์ ํํ ์์ง ๋ชปํ์ง๋ง ์ซ์ ์ ํ์ผ๋ก ํด๊ฒฐํ๋ ๊ฒ์ด ์ด๋ฌํ ์ธก๋ฉด์ ๋ํ ๋์ผํ ์ดํด๋ฅผ ๊ณต์ ํ์ง ์๋ ์ซ์ ์ ํ ์ฌ์ฉ์์๊ฒ ๋ฌด์ฌ์ฝ ํจ์ฌ ๋ ๋ง์ ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๊ธฐ๊ฐ ๊บผ๋ ค์ง๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ฒ์ด ๋ชจ๋ ์ฌ๋์๊ฒ ์ดํด๊ฐ ๋๋ ๋ค๋ฅธ ๊ณณ์ด ์ด๋ ์์ต๋๊น? ์ด ์์ ์์ ์๊ฐํ๋ ๊ฒ๋ฟ์ ๋๊น?
๋ฐ์ดํธ ๋ฐฐ์ด์ ์ ๋ฌํ๋ API๋ฅผ ๋ค๋ฃจ๊ณ ์์ผ๋ฏ๋ก ๋ฐ์ดํธ ์ ํ์ ์ ์ํ๊ณ ์ถ์ต๋๋ค.
type byte = 0x00..0xFF
type bytes = byte[]
์ด๊ฒ์ Uint8Array
์์
ํ ๋๋ ์ ์ฉํฉ๋๋ค.
๋น์ ์ด ๋์ ๊ฐ์ผ๋ฉฐ ํ์ฌ ์ค์ ๋ก ์ฌ์ฉํ ์ ์๋ ๋ฒ์ ์ ํ์ ์ป๋ ๋ฐ ์ฐธ์์ฑ์ด ์๋ค๋ฉด ๋ค์์ ์๋ ์ค์ธ ๋ฒ์ ์ ํ์ ์ฝ๋ ์ค๋ํซ์ ๋๋ค.
TL;DR,
๋ฒ์ ์ ํ์ ์ด์ ์๋ํ ์ ์์ต๋๋ค.
interface CompileError<_ErrorMessageT> {
readonly __compileError : never;
}
///////////////////////////////////////////////
type PopFront<TupleT extends any[]> = (
((...tuple : TupleT) => void) extends ((head : any, ...tail : infer TailT) => void) ?
TailT :
never
);
type PushFront<TailT extends any[], FrontT> = (
((front : FrontT, ...tail : TailT) => void) extends ((...tuple : infer TupleT) => void) ?
TupleT :
never
);
type LeftPadImpl<TupleT extends any[], ElementT extends any, LengthT extends number> = {
0 : TupleT,
1 : LeftPad<PushFront<TupleT, ElementT>, ElementT, LengthT>
}[
TupleT["length"] extends LengthT ?
0 :
1
];
type LeftPad<TupleT extends any[], ElementT extends any, LengthT extends number> = (
LeftPadImpl<TupleT, ElementT, LengthT> extends infer X ?
(
X extends any[] ?
X :
never
) :
never
);
type LongerTuple<A extends any[], B extends any[]> = (
keyof A extends keyof B ?
B :
A
);
///////////////////////////////////////////////////////
type Digit = 0|1|2|3|4|5|6|7|8|9;
/**
* A non-empty tuple of digits
*/
type NaturalNumber = Digit[];
/**
* 6 - 1 = 5
*/
type SubOne<D extends Digit> = {
0 : never,
1 : 0,
2 : 1,
3 : 2,
4 : 3,
5 : 4,
6 : 5,
7 : 6,
8 : 7,
9 : 8,
}[D];
type LtDigit<A extends Digit, B extends Digit> = {
0 : (
B extends 0 ?
false :
true
),
1 : false,
2 : LtDigit<SubOne<A>, SubOne<B>>
}[
A extends 0 ?
0 :
B extends 0 ?
1 :
2
];
//false
type ltDigit_0 = LtDigit<3, 3>;
//true
type ltDigit_1 = LtDigit<3, 4>;
//false
type ltDigit_2 = LtDigit<5, 2>;
/**
* + Assumes `A` and `B` have the same length.
* + Assumes `A` and `B` **ARE NOT** reversed.
* So, `A[0]` is actually the **FIRST** digit of the number.
*/
type LtEqNaturalNumberImpl<
A extends NaturalNumber,
B extends NaturalNumber
> = {
0 : true,
1 : (
LtDigit<A[0], B[0]> extends true ?
true :
A[0] extends B[0] ?
LtEqNaturalNumberImpl<
PopFront<A>,
PopFront<B>
> :
false
),
2 : never
}[
A["length"] extends 0 ?
0 :
number extends A["length"] ?
2 :
1
];
type LtEqNaturalNumber<
A extends NaturalNumber,
B extends NaturalNumber
> = (
LtEqNaturalNumberImpl<
LeftPad<A, 0, LongerTuple<A, B>["length"]>,
LeftPad<B, 0, LongerTuple<A, B>["length"]>
> extends infer X ?
(
X extends boolean ?
X :
never
) :
never
);
//false
type ltEqNaturalNumber_0 = LtEqNaturalNumber<
[1],
[0]
>;
//true
type ltEqNaturalNumber_1 = LtEqNaturalNumber<
[5,2,3],
[4,8,9,2,3]
>;
//false
type ltEqNaturalNumber_2 = LtEqNaturalNumber<
[4,8,9,2,3],
[5,2,3]
>;
//true
type ltEqNaturalNumber_3 = LtEqNaturalNumber<
[5,2,3],
[5,2,3]
>;
//true
type ltEqNaturalNumber_4 = LtEqNaturalNumber<
[5,2,2],
[5,2,3]
>;
//false
type ltEqNaturalNumber_5 = LtEqNaturalNumber<
[5,1],
[2,5]
>;
//false
type ltEqNaturalNumber_6 = LtEqNaturalNumber<
[2,5,7],
[2,5,6]
>;
type RangeLt<N extends NaturalNumber> = (
number &
{
readonly __rangeLt : N|undefined;
}
);
type StringLengthLt<N extends NaturalNumber> = (
string & { length : RangeLt<N> }
);
type AssertStringLengthLt<S extends StringLengthLt<NaturalNumber>, N extends NaturalNumber> = (
LtEqNaturalNumber<
Exclude<S["length"]["__rangeLt"], undefined>,
N
> extends true ?
S :
CompileError<[
"Expected string of length less than",
N,
"received",
Exclude<S["length"]["__rangeLt"], undefined>
]>
);
/**
* String of length less than 256
*/
type StringLt256 = string & { length : RangeLt<[2,5,6]> };
/**
* String of length less than 512
*/
type StringLt512 = string & { length : RangeLt<[5,1,2]> };
declare function foo<S extends StringLengthLt<NaturalNumber>> (
s : AssertStringLengthLt<S, [2,5,6]>
) : void;
declare const str256 : StringLt256;
declare const str512 : StringLt512;
foo(str256); //OK!
foo(str512); //Error
declare function makeLengthRangeLtGuard<N extends NaturalNumber> (...n : N) : (
(x : string) => x is StringLengthLt<N>
);
if (makeLengthRangeLtGuard(2,5,6)(str512)) {
foo(str512); //OK!
}
declare const blah : string;
foo(blah); //Error
if (makeLengthRangeLtGuard(2,5,5)(blah)) {
foo(blah); //OK!
}
if (makeLengthRangeLtGuard(2,5,6)(blah)) {
foo(blah); //OK!
}
if (makeLengthRangeLtGuard(2,5,7)(blah)) {
foo(blah); //Error
}
์ฌ๊ธฐ์์ CompileError<>
์ ํ์ ์ฌ์ฉํฉ๋๋ค.
https://github.com/microsoft/TypeScript/issues/23689#issuecomment -512114782
AssertStringLengthLt<>
์ ํ์ ๋ง๋ฒ์ด ์ผ์ด๋๋ ๊ณณ์
๋๋ค.
์ ํ ์์ค ์ถ๊ฐ๋ฅผ ์ฌ์ฉํ๋ฉด str512 + str512
๊ฐ์ง ์ ์๊ณ str1024
์ป์ ์ ์์ต๋๋ค.
https://github.com/microsoft/TypeScript/issues/14833#issuecomment -513106939
@AnyhowStep ์๋ฃจ์ ์ ๋ณด๋ฉด ๋ ๋์ ์์ ์๋ฃจ์ ์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ ํ ๊ฐ๋๋ฅผ ๊ธฐ์ตํ์ญ๋๊น?:
/**
* Just some interfaces
*/
interface Foo {
foo: number;
common: string;
}
interface Bar {
bar: number;
common: string;
}
/**
* User Defined Type Guard!
*/
function isFoo(arg: any): arg is Foo {
return arg.foo !== undefined;
}
/**
* Sample usage of the User Defined Type Guard
*/
function doStuff(arg: Foo | Bar) {
if (isFoo(arg)) {
console.log(arg.foo); // OK
console.log(arg.bar); // Error!
}
else {
console.log(arg.foo); // Error!
console.log(arg.bar); // OK
}
}
doStuff({ foo: 123, common: '123' });
doStuff({ bar: 123, common: '123' });
๋ฐ๋ผ์ ๋ค์ ์ฝ๋๋ฅผ ์ดํด๋ณด์ญ์์ค.
class NumberRange {
readonly min: number;
readonly max: number;
constructor(min:number, max:number, ) {
if (min > max) {
throw new RangeError(`min value (${min}) is greater than max value (${max})`);
} else {
this.min = min;
this.max = max;
}
}
public isInRange = (num: number, explicit = false): boolean => {
let inRange: boolean = false;
if (explicit === false) {
inRange = num <= this.max && num >= this.min;
} else {
inRange = num < this.max && num > this.min;
}
return inRange;
};
}
const testRange = new NumberRange(0, 12);
if(testRange.isInRange(13)){
console.log('yay')
}else {
console.log('nope')
}
๊ทธ๊ฒ์ ๋จ์ง ์์ด๋์ด์ด์ง๋ง ์ ํ ๊ฐ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฒ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ฌธ์ ๋ ๋น์ ์ด ์ด๊ฒ์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
declare const a : number;
declare let b : (>= 5);
const testRange = new NumberRange(12, 20);
if (testRange.isInRange(a)) {
b = a; //ok
} else {
b = a; //compile error
}
์ ํ ๊ฐ๋๋ง์ผ๋ก๋ ๋ง์กฑ์ค๋ฌ์ด ์๋ฃจ์ ์ด
๋ํ ๊ทํ์ ์์ ๋ ์ ํ ๊ฐ๋๋ ์ฌ์ฉํ์ง ์์ต๋๋ค.
์์ ์ด๋ฆฌ์์ ํดํค ์ฅ๋๊ฐ ์์ ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฒ์ ์ ํ์ด ๋ค๋ฅธ ๋ฒ์ ์์ ์๋ ๊ฒฝ์ฐ ๋ฒ์ ์ ํ์ ๋ค๋ฅธ ๋ฒ์ ์ ํ์ ํ ๋นํ ์ ์์ต๋๋ค(ํจ์ ๋งค๊ฐ๋ณ์๋ฅผ ํตํด).
๋ํ ํ๋ฆฌ๋ฏธํฐ๋ธ์์ ์ฌ์ฉ๋๋ ํ๊ทธ ์ ํ, ๋ช ๋ชฉ ์ ํ ๋ฐ ๊ฐ ๊ฐ์ฒด๋ ์ผ๋ฐ์ ์ผ๋ก ์ ํ ์์คํ ์ด ์ถฉ๋ถํ ํํ๋์ง ์๋๋ค๋ ์ ํธ์ ๋๋ค.
ํ๊ทธ ์ ํ์ ์ฌ์ฉํ๋ ์ด๋ฆฌ์์ ์ฅ๋๊ฐ ์์ ๋ ๋งค์ฐ ์ธ์ฒด๊ณตํ์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ ์ซ์ดํฉ๋๋ค. ๋ฒ์๊ฐ ๊ธฐ๋ณธ์ด ๋๋ ๊ฒ์ด ๋ ๋์ ๋ฐฉ๋ฒ์ ๋ํด์๋ ์ด ๊ธด ์ฃผ์์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
https://github.com/microsoft/TypeScript/issues/6579#issuecomment -548249683
ํ์ฌ Typescript ๋ฒ์ ์ผ๋ก ์ด๋ฅผ ๋ฌ์ฑํ ์ ์์ต๋๋ค.
// internal helper types
type IncrementLength<A extends Array<any>> = ((x: any, ...xs: A) => void) extends ((...a: infer X) => void) ? X : never;
type EnumerateRecursive<A extends Array<any>, N extends number> = A['length'] extends infer X ? (X | { 0: never, 1: EnumerateRecursive<IncrementLength<A>, N> }[X extends N ? 0 : 1]) : never;
// actual utility types
export type Enumerate<N extends number> = Exclude<EnumerateRecursive<[], N>, N>;
export type Range<FROM extends number, TO extends number> = Exclude<Enumerate<TO>, Enumerate<FROM>>;
// usage examples:
type E1 = Enumerate<3>; // hover E1: type E1 = 0 | 1 | 2
type E2 = Enumerate<10>; // hover E2: type E2 = 0 | 1 | 3 | 2 | 4 | 5 | 6 | 7 | 8 | 9
type R1 = Range<0, 5>; // hover R1: type R1 = 0 | 1 | 3 | 2 | 4
type R2 = Range<5, 11>; // hover R2: type R2 = 10 | 5 | 6 | 7 | 8 | 9
๋๋ ํฌ๊ด์ ์ธ ์์ ์ธ๋ฑ์ค์ ๋ฐฐํ์ ์ข ๋ฃ ์ธ๋ฑ์ค๋ฅผ ๊ฐ๋ ๊ด๋ก๋ฅผ ๋ฐ๋์ง๋ง ๋น์ ์ ๋น์ ์ ํ์์ ๋ฐ๋ผ ๊ทธ๊ฒ์ ์กฐ์ ํ ์ ์์ต๋๋ค.
๋๊ธ์ vs ์ฝ๋ ํธ๋ฒ ํํธ๊ฐ ์์ต๋๋ค.
ํธ๋ฒ ํํธ์ ์ซ์๋ ๋ฌด์์๋ก ์ ๋ ฌ๋ฉ๋๋ค.
์ฌํ๊ฒ๋ ์ฝ 10๊ฐ ์์๊น์ง๋ง ์๋ํฉ๋๋ค :(
ํธ์ง: Enumerate
๋ 15
์ฌ๊ท(0 - 14)๊น์ง๋ง ์ฒ๋ฆฌํ ์ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
@์๋๊ฐ๋ฏธ92
์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด Enumerate๊ฐ ์ต๋ 40๊ฐ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
์ด๊ฒ์ ์ฌ์ ํ โโ์ ํ์ด์ง๋ง ์ค์ ๋ก๋ ๊ทธ๋ ๊ฒ ๊ฐํนํ์ง ์์ ์ ์์ต๋๋ค.
type PrependNextNum<A extends Array<unknown>> = A['length'] extends infer T ? ((t: T, ...a: A) => void) extends ((...x: infer X) => void) ? X : never : never;
type EnumerateInternal<A extends Array<unknown>, N extends number> = { 0: A, 1: EnumerateInternal<PrependNextNum<A>, N> }[N extends A['length'] ? 0 : 1];
export type Enumerate<N extends number> = EnumerateInternal<[], N> extends (infer E)[] ? E : never;
export type Range<FROM extends number, TO extends number> = Exclude<Enumerate<TO>, Enumerate<FROM>>;
type E1 = Enumerate<40>;
type E2 = Enumerate<10>;
type R1 = Range<0, 5>;
type R2 = Range<5, 34>;
๊ทธ๋ฆฌ๊ณ ์ด์ ์ด๋ป๊ฒ ๋ ๋ง๋ฒ์ฒ๋ผ ์ ๋ ฌ๋์์ต๋๋ค ;).
์ ๋ฅผ ์ํ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ [1, 255]
, [1, 2048]
, [1, 4096]
, [20, 80]
๋ฑ๊ณผ ๊ฐ์ ๋ฒ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํฐ ๊ณต์ฉ์ฒด ์ ํ์ ๋ง๋ค๋ฉด TS๊ฐ ๋๋ผ๊ฑฐ๋ ๋๋ ค์ง ์ ์์ต๋๋ค. . ๊ทธ๋ฌ๋ ์ด๋ฌํ ์๋ฃจ์
์ "๋ ์์" ๋ฒ์์์ ํ์คํ ์๋ํฉ๋๋ค.
@์๋ฌดํผ์คํ
์ฌ๊ท ํ์๊ฐ ํ๊ณ๋ผ๋ ๊ฒ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ฒ์๋ฅผ ๋ฌ์ฑํ๋ ค๋ฉด ์ ํ ์ ์ ๋ด์์ ๋จ์ผ ๋น์ฌ๊ท ์ฐ์ฐ์ผ๋ก ์ซ์ ๋๋๊ธฐ/๊ณฑ์
์ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํฉ๋๋ค.
์ฑ๋ฅ์ ์ฌ์ ํ โโ๋ฌธ์ ์ ๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ์ด์ ์ ๋ํ ์ฑ์์ ์ ์ฉํ ๊ณต์ฉ์ฒด ์ ํ์ ์ ๋ณํด์ผ ํ์ต๋๋ค. ํฅ๋ฏธ๋ก์ด ์์ ์ผ ์ ์์ง๋ง ํ์คํ ์๋ฃจ์ ์ ์๋๋๋ค.
์์ง ์๋ฒฝํ ์๋ฃจ์ ์ด ์๋ ๊ฒ ๊ฐ์๋ฐ์?
๋๋ ์ด๊ฒ์ด ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ํ๋ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค(๊ทธ๋ฌ๋ ์ด๋ ต๊ธด ํ์ง๋ง).
type X => (number >= 50 && number > 60 || number = 70) || (string.startsWith("+"))
(์ฆ, ๋ณ์๊ฐ ์ ํ์ผ๋ก ๋์ฒด๋๋ค๋ ์ ์ ์ ์ธํ๊ณ ์ฌ๊ธฐ์์ ์ผ๋ฐ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ/ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์)
๋ด ์ดํด์์ ํ๋ ์ธ์ด = ์ผ๋ฐ ๋ ผ๋ฆฌ + ๋ฉํ ๋ ผ๋ฆฌ, ์ฌ๊ธฐ์ ๋ฉํ ๋ ผ๋ฆฌ = ์ฝ๋ ๊ฒ์ฌ + ์ฝ๋ ์์ฑ. ๋ง์ ์์ ์ด ๋ฉํ ๋ ผ๋ฆฌ ๊ตฌ๋ฌธ์ ์ฐ์ํ ๋ฐฉ์์ผ๋ก ๋ณํฉํ๋ ค๊ณ ํฉ๋๋ค.
์ด์ฉ๋ฉด ์ฐ๋ฆฌ๋ ๋ฒ์ ์ ํ์ ์ผ์ข ์ ์คํ์ด ์๋๋ผ ํต์ฌ ๊ฐ๋ ์ผ๋ก ๊ฐ์ ํ ์ ์์ต๋๊น?
// number literal extend `number` despite the fact
// that `number` is not union of all number literals
type NumberLiteralIsNumber = 5 extends number ? true : false // true
// so if we will define Range (with some non-existing syntax which is clearly should be done in lib internals)
type Range<MIN extends number, MAX extends number> = MAX > MIN ? 5 and 2NaN : MAX === MIN ? MAX : MIN..MAX
// and assume that `number` is Range<-Infinity, +Infinity>
type NumberIsInfinitRange = number extends Range<-Infinity, +Infinity> ?
Range<-Infinity, +Infinity> extends number ? true : false :
false // true
// following things will be true
type AnyRangeIsNumber<T extends number, K extends Number> =
Range<T, K> extends number ? true : false // true
type NestedRangeIsNumber<T extends number, K extends number, S extends number> =
Range<T, Range<K, S>> extends number ? true : false // true
์ด๋ฅผ ์๋ฃํ๋ ค๋ฉด ์ผ๋ถ ๊ฒฝ์ฐ์ ๋์์ ์ ์ธํด์ผ ํฉ๋๋ค.
Range<T, T> === T
์ ์Range<5, 1> === NaN
์ ์Range<NaN, T> === Range<T, NaN> === NaN
๊ฐ์ ๊ฐ์ ์กด์ฌํ ์ ์์ต๋๋ค.Range<1 | 2, 5> === Range<2, 5>
์ฒซ ๋ฒ์งธ ์ ํ ๋งค๊ฐ๋ณ์๋ก ๋ ํฐ ์ซ์์ ๊ฐ๋ฅ์ฑ์ ๋ฒ์๋ฅผ ๋ ์งง๊ฒ ์ ํํฉ๋๋ค.Range<1, 4 | 5> === Range<1, 4>
๋ ๋ฒ์งธ ์ ํ ๋งค๊ฐ๋ณ์๋ก ๋ฎ์ ์ซ์์ ๊ฐ๋ฅ์ฑ์ ๋ฒ์๋ฅผ ๋ ์งง๊ฒ ์ ํํฉ๋๋ค.1.5 extends Range<1, 2>
๋ ์ ์์ true์ฌ์ผ ํฉ๋๋ค.Range<Range<A, B>, C> === NaN extends Range<A, B> ? NaN : Range<B, C>
๋ 5์ 3์ ์ด์ด์ง๋๋ค.Range<A, Range<B, C>> === NaN extends Range<B, C> ? NaN : Range<A, B>
๋ 6๊ณผ 3์ ์ด์ด์ง๋๋ค.Ranges ์์ Ranges์ ๋ํด ์กฐ๊ธ:
type RangeIsInsideRange<T extends Range<any, any>, K extends Range<any, any>> =
T extends Range<infer A, infer B>
? K extends Range<infer C, infer D>
? NaN extends Range<A, C>
? false
: NaN extends Range<B, D>
? false
: true
: never
: never
๋ฒ์ ํ์ ์ ํ์ ์ ํ ์์ค ๋น๊ต ํจ์ (a: T, b: T) => '<' | '=' | '>'
์ ๊ฐ์ ์ผ๋ฐ์ ์ธ ๋ฐฉ์์ผ๋ก ์ ์ํ ์๋ ์์ต๋๋ค.
...์ ํ ์์ค์์ ์ผ๋ฐ JS ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํ ์ ์์ด ์์ต๋๊น?
๊ทธ ์์ฒด๋ก๋ ์ ์์ด ์์ง๋ง ์ด์ ์ ๋น ๋ฅธ ํ๋กํ ํ์ ์
@yudinns ๋ฌธ์ ๋ Range๊ฐ ์ต์ํ ์ด ์ด๋ฆ์ ์กด์ฌํ๋ฏ๋ก ํผ๋์ค๋ฌ์ธ ์ ์์ต๋๋ค. https://developer.mozilla.org/en-US/docs/Web/API/range ์ฐธ์กฐ ๋ํ ์ ์ํ ์ ์๋ ๊ธฐ๋ฅ์ด ๊ทธ๋ฆฌ์์ <1, n+2>
์ ๊ฐ์ ์์ด - ํ๋ ์ด์์ ๋ณต์กํ ๋ฐฉ์ ์์์ ์์ํ๋ 2๋จ๊ณ.
์ด TC39 ์ ์ ์ ๊ตฌํ๋๊ธฐ ์ ์ ์๋ง๋ 4๋จ๊ณ์ ๋๋ฌํ ๊ฒ์
๋๋ค.
ํฐ์ผ์ 3์ธ์
๋๋ค.
์ ์: ์ ๊ท์ ๊ฒ์ฆ ๋ฌธ์์ด ์ ํ: https://github.com/Microsoft/TypeScript/issues/6579
(๊ด๋ จ SO ์ง๋ฌธ: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp)
number in range
eg if 1 in 1..2
๋๋ ์ธํด๋ฃจ์๋ธ if 1 in 1..=2
๊ณผ ๊ฐ์ ์์
์ ํ ์ ์๋ค๋ฉด ๋ํ ๋ฉ์ง ๊ฒ์
๋๋ค. https://doc.rust-lang.org/reference/ ํํ/๋ฒ์-expr.html . ๊ทธ๊ฒ์ ๋ง์ ๊ณต๊ฐ์ ์ ์ฝ ํ ๊ฒ์
๋๋ค
python๊ณผ rust์๋ ์ด๋ฏธ ์ ํ์ด ์ง์ ๋ ๋ฒ์ ๊ธฐ๋ฅ์ด ์๋์?
์ฃผ์ ๋ชฉ์ ๊ณผ ๊ฐ์ฅ ํฐ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์ซ์ ๋ฒ์์ธ ๋์ ๋ฐํด๋ฅผ ์ฌ๋ฐ๋ช
ํ๊ฑฐ๋ ๋ฌธ์์ด, ๋ถ๋ ์์์ ๋ฑ์ ์ฌ์ฉํ์ฌ ์ถ๊ฐ ์ผ๋ฐํํ๋ ๋์ ๋ค๋ฅธ ์ธ์ด๋ก ๊ธฐ์กด ์๋ฃจ์
์ ๋ค์ ๊ตฌํํ ์ ์์ต๋๊น? ๋์ค์ ํ์ํ ๋ ๋ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ ๋ ๋ฒ ์ด์ ๋ง๋ฌ๊ณ ์ฌ๊ธฐ์ 0...1 ์ฌ์ด์ ๋ถ์์ธ ์ ํ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๊ฒ์ํ์ต๋๋ค. ์ด๊ฒ์ https://news.ycombinator.com/item?id= ์์ ๋ ผ์๋๊ณ
@andrewphillipo ๋๋ ๊ทธ๊ฒ์ด ๋ ผ์๋๋ ๊ฒ์ ๋ณด์๊ณ ์คํ ๊ตํ์ ๋ํ ๋ต๋ณ ์ค ํ๋ ์์ Unit Interval ์ด๋ผ๋ ์ฉ์ด์ ๋ํด ๋ฐฐ์ ์ต๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ธ ์ปจํ ์คํธ์์ ํด๋น ํน์ ๋ฒ์๋ฅผ ์ฐธ์กฐํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
์ ํ์ผ๋ก์์ ๋ฒ์๊ฐ ์ ํ ์คํฌ๋ฆฝํธ์์ ๊ตฌํ๋ ๊ฒฝ์ฐ ์๋ง๋ UnitInterval
์ ์ญ ์ ํ์ผ๋ก ์ ์ํ์ฌ ํ๋ก๊ทธ๋๋ฐ์์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํ ๋ช ๊ฐ์ง ๊ณตํต ๋ช
๋ช
๋ฒ์ ์ฅ๋ คํ ์ ์์ต๋๋ค.
์ UnitInterval์ 0...1 ๋ฒ์์ ์ฌ๋ฐ๋ฅธ ์ด๋ฆ์ด๋ฏ๋ก ์ ํ์ ๋ง์ต๋๋ค! ์ฌ์ ํ ์ซ์์ ์ด๋ฆ์ด ์ ํํ์ง ์์ผ๋ฏ๋ก ์ด๋ฌํ ์ ํ์ ์ฌ์ฉํ์ฌ ์ฝ๋๋ฅผ ๋ ์ ํํ๊ฒ ์ค๋ช ํ๋ ๋ฐ ์ด๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ฉด ํ๋ฅญํ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ Rust์ ์ ํ ์์คํ ์์ ํ๋ ์๋์์ ์ด๋ป๊ฒ ์๋ํฉ๋๊น?
CantorSpace
๊ฐ ๋๋ฌด ๊ณผ์ฅ๋์ง ์์ผ๋ฉด ์ปดํจํฐ๊ฐ ์ดํดํ๋ [0, 1]
์ฌ์ด์ "๋ชจ๋ " ์ค์์ "๋ฒ์"์ ๋ํ ๊ณต์ ํ ์ ์๊ฐ ๋ ๊ฒ์
๋๋ค. ์ปดํ์ผ์์ ๊ฐ์ด ํ ๋นํ๋ ๊ฒ์ ์ ์ถ ํ ์์๋ ํ๋ถ ๋ฐ ์๋ถ ์๋ฐ ์คํฌ๋ฆฝํธ์์ ๊ฒฝ๊ณ Math.floor
๋๋ Math.ceil
๋ถํฐ Math.ceil(0) === 0
, ๊ทธ๋ฆฌ๊ณ Math.floor(1) === 1
ํ๋์ด ๋ถํํ ์ฌ๋.
๋ชจ๋ ์ซ์ ์งํฉ (0, 1)
๊ฐ ๋์ ์ฌ์ฉ๋๋ฉด ์์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์๋ํ์ง๋ง ์ผ์ ์ธ์ด์์ ๋ฐฑ๋ถ์จ๋ก ์ฐธ์กฐ๋๋ ๊ฐ์ ์ ์ธํ๋ ๊ฒ์ ์ข์ง ์์ต๋๋ค. ๊ฐ๋ฅํ๋ค๋ฉด ์ปดํ์ผ๋ฌ๊ฐ ๊ฒฝ๊ณ๋ฅผ ํฌํจํ๋๋ก ํ๋ ๊ฒ์ด ์ข์ ๊ฒ์
๋๋ค. ์๋ง๋ ์์ง ์ผ์ด์ค 0๊ณผ 1์ ๋ํ ์๊ฒฉํ ===
๊ฒ์ฌ๋ฅผ ํตํด์์ผ ๊ฒ์
๋๋ค.
๋๋ ์ ์์๋ 1~~3
๋ฅผ ์ฌ์ฉํ๊ณ float ์๋ 0.1~0.5
๋ฅผ ์ฌ์ฉํ์๊ฒ ์ต๋๊น?
~
๋ ์ด๋ฏธ ๋จํญ ๋นํธ NOT ์ฐ์ฐ์์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
๊ทธ ๋น์ด๋จน์ ์๋ ์ ๋ํด ์ด์ผ๊ธฐํด์ผ ํ๋ ์ด์ ๋ ์ ์์ ๋ํ ๋ฌธ์ ์
๋๋ค. 99.99%๋ ์ ์ ๋ฌธ์ 0.001%๋ ๋ถ๋ ์์์ ๋ฌธ์ ์
๋๋ค.
์ผ๋ฐ์ ์ธ ์๋ฃจ์
์ ์ฝ๊ฒ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ์๋
์ ์ ์ด๋ฏธ ๊ตฌํ๋ ๊ฒ์ฒ๋ผ ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ๋ณผ ์ ์๋ 0..10์ ์ซ์ ๋ฒ์๋ก ๊ฐ๋ณด๊ฒ ์ต๋๋ค.
ํ๋กํธ ์๊ธฐ ๊ทธ๋งํด
์ฒญ๊ตฌ์๋ฅผ ๋ถํ ํ๊ณ int ๊ฒฝ์ฐ์ ๋ํด ์ด ์ ์์ ํ์ฅํ ์ ์์ต๋๋ค.
https://gist.github.com/rbuckton/5fd81582fdf86a34b45bae82d842304c
๊ทธ๋ฆฌ๊ณ float์ ๊ฒฝ์ฐ ํ์ฌ ์ด ๋ฌธ์ ์ ๋ช ๊ฐ์ง ์์ด๋์ด(์ฃผ๋ก @AnyhowStep, ๊ธฐ๋ณธ์ ์ผ๋ก Open-Interval-Type์ ๊ฐ์ง ์ ์๋ ๊ธฐ๋ฅ)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค๋ฅธ ๋์์ธ ์ ์์ ์์ ์ค์ ๋๋ค.
๊ทธ๋ฅ ๊ฐ๋จํ๊ฒ ์ ์ง
x..y
๋ ์ ์์๋ง ํด๋นํฉ๋๋ค.
0.1..2
์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
1..2.1
๋ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ์งํ ์ ์๋ ์ ์๊ฐ ์๋ ๋ชจ๋ ์ซ์.
๊ตฌํ ๋
ผ๋ฆฌ๋ฅผ ๋ณต์ฌํ์ญ์์ค.
https://en.m.wikibooks.org/wiki/Ada_Programming/Types/range
๋๋
https://kotlinlang.org/docs/reference/ranges.html
๋๋
https://doc.rust-lang.org/reference/expressions/range-expr.html
๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ํ๋ฃจ๋ผ๊ณ ๋ถ๋ฆ
๋๋ค.
โ
๋ฐํด๋ฅผ ์ฌ๋ฐ๋ช
ํ ํ์๊ฐ ์์ต๋๋ค
โ
์๋ ๋ฅผ ๊ณ ๋ คํ ํ์๊ฐ ์์ต๋๋ค.
โ
์ธ์ด ๊ฐ ์ผ๊ด์ฑ
โ
๊ธฐ์กด ์์ค์์ ํ
์คํธ ๋ฐ ๋ณต์ฌ ๊ฐ๋ฅํ ์์ ์ ์ธ ์ฝ๋
"int" ๊ธฐ๋ฐ ์ ํ ๊ฒ์ฌ๋ ๋ชจ๋ ๊ณ ์ ์ ์ 0..1000์ ํฉ์งํฉ์ผ๋ก ์ ํ ๊ฐ์ ํ๋ ์ฝ๋ฉํ์ฌ ์ซ์ < 1000์ ๋ํด ์ฌ์ํ๋ฏ๋ก "๋ค์ ํ ํ์๊ฐ ์์ต๋๋ค"๋ผ๊ณ ๋งํฉ๋๋ค. - ๋ฐํด๋ฅผ ๋ฐ๋ช ํ๋ผ"๋ ๊ฒ์ ์ฝ๊ฐ ์์ด๋ฌ๋ํ๋ค. ๊ฐ๋จํ ์ฌ์ฉ ์ฌ๋ก์์ ์ด๋ฏธ ์๋ํ๋ ๊ฒ์ ์ฌ์ฉํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
์คํ๋ ค ๋ฌด๋ฆฌ์์ ๊ฐ์ ๊ฒ์ ์ดํดํ๋ ์ ํ ์ ์๋ฅผ ํ์ฉํ ์ฌ์ง๊ฐ ์๋์ง ํ์ธํ๊ณ ์ถ์ต๋๋ค. ๋ผ๋์์ผ๋ก ์์ ํ ๋ ์ปดํ์ผ ํ์์ ๋ถ๋ณ๋์ ๊ฐ์งํ๋ ๊ธฐ๋ฅ์ ํฅ๋ฏธ๋ก์ด ์ฌ์ฉ ์ฌ๋ก๊ฐ ๋ ๊ฒ์ ๋๋ค. ๋ฒ์ ๊ฐ ๊ฒฝ๊ณ์ ๋ํ ์ธ์๋ก ฯ๋ฅผ ์ง์ํ๋ ๊ฒ์ ์ด ๊ธฐ๋ฅ์ด ์๋ํ ๋๋ก ์๋ํ๋ค๊ณ ์ฃผ์ฅํ๊ธฐ์ ์ข์ ๋์์ ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์๋ ๋ช
์์ ์ธ integer
๊ฐ ์์์ ๋ช
์ฌํ์ญ์์ค. ๋ชจ๋ ๊ฒ์ float๋ก ์ ์ฅ๋๋ number
์
๋๋ค. ๋ฒ์ ์ ํ ์ฐ์ฐ์๊ฐ ๊ตฌํ๋ ๊ฒฝ์ฐ number
๊ฐ ์ฒ๋ฆฌํ ์ ์๋ ๋ชจ๋ ๊ฐ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
explicit
์ ์์ ๋ฐ๋ฅธ @aMoniker : BigInt
bigint์ ๊ฒฝ์ฐ์๋ bigint๊ฐ MySQL ์๋ช /๋น์๋ช bigint์ ๋ง๋์ง ํ์ธํ๋ ๊ฒ์ฒ๋ผ ํตํฉ์ด ํด๊ฒฐํ ์ ์๋ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ ๋ํ intrinsic
๋ฒ์ ์ ํ ์ ๋ง๋๋ ๊ฒ์ ์ด๋ป์ต๋๊น?
lib.es5.d.ts
(๋๋ bigints ์ง์์ ํฌํจํ๋ ๊ฒฝ์ฐ lib.es2020.bigint.d.ts
)type GreaterThan<N extends number | bigint> = intrinsic
type GreaterThanOrEqualTo<N extends number | bigint> = GreaterThan<N> | N
type LessThan<N extends number | bigint> = intrinsic
type LessThanOrEqualTo<N extends number | bigint> = LessThan<N> | N
/**
* prevent `GreaterThan` and `LessThan` from desugaring
* (in the same way that `number` does _not_ desugar to `-Infinity | ... | Infinity`)
*/
type GreaterThanOrEqualTo2 = GreaterThanOrEqualTo<2>
type LessThan8 = LessThan<8>
type GreaterThanOrEqualTo2_And_LessThan8 = GreaterThanOrEqualTo2 & LessThan8
type LessThan2_Or_GreaterThanOrEqualTo8 = LessThan<2> | GreaterThanOrEqualTo<8> // inverse of `GreaterThanOrEqualTo2_And_LessThan8` (would be nice to be able to just do `Exclude<number | bigint, GreaterThanOrEqualTo2_And_LessThan8>` but that might be wishful thinking)
type LessThan2_And_GreaterThanOrEqualTo8 = LessThan<2> & GreaterThanOrEqualTo<8> // `never`
type GreaterThanOrEqualTo2_Or_LessThan8 = GreaterThanOrEqualTo2 | LessThan8 // `number | bigint`
type RangesAreNumbersOrBigIntsByDefault = LessThan8 extends number | bigint ? true : false // `true` (the user could always narrow this on a per-range basis, e.g. `LessThan8 & number`)
type RangesAcceptUnions = LessThan<7n | 7.5 | 8> // `LessThan<8>`
type RangesAcceptOtherRanges1 = LessThan<LessThan8> // `LessThan8`
type RangesAcceptOtherRanges2 = LessThan<GreaterThanOrEqualTo2> // `number | bigint`
type RangesSupportBeingInAUnion = (-6 | 0.42 | 2n | 2 | 3) | LessThan<2> // `LessThan<2> | 2n | 2 | 3`
type RangesSupportBeingInAnIntersection = (-6 | 0.42 | 2n | 2 | 3) & LessThan<2> // `-6 | 0.42`
type RangesSupportBeingInAUnionWithOtherRanges = LessThan<2> | LessThan8 // `LessThan8`
type RangesSupportBeingInAnIntersectionWithOtherRanges = LessThan<2> & LessThan8 // `LessThan<2>`
@RyanCavanaugh
์ค๋๋ ์ ๊ณต์ฉ์ฒด ๊ตฌํ์ ์ด๋ ๊ฒ ํฐ ๊ณต์ฉ์ฒด๋ฅผ ๊ตฌํํ๋ ๋ฐ ์์ ํ ๋ถ์ ํฉํ๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์๋ ๋ช ๊ฐ์ง ๊ฐ๋ ฅํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ํ์ํฉ๋๋ค. ์ด๋ฐ ๊ธ์ ์ฐ๋ฉด ๋ฌด์จ ์ผ์ด...
๋ค์์ int ์ ํ์ด ์์ผ๋ฉด ๊ฑด์ ํ์ง ์์ต๋๋ค.
const arr: string[] = ['a', 'b', 'c']
const item = arr[1.01] // Typescript inferred this as string but actually it is undefined
console.log(item) // Will print undefined, we miss inferred the type
๋ค์ ์ ํ์ ์ฌ์ฉํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
type TUInt = 0..4294967295;
Int32
๋ฐ Int64
์ ํ์ ์ฌ์ฉํ๋ ๋ ๋ค๋ฅธ ์ฌ์ฉ ์ฌ๋ก๋ ํนํ ์ฌ๋๋ค์ด ์ฝ๋์ ์ฃผ์์ ๋ฌ๊ธฐ ์์ํ ๋์
๋๋ค ... ๋ค๋ฅธ ์ธ์ด์์ ๋ ๋์ ์ํธ ์ด์ฉ์ฑ์ ๋ฌธ์ ์ด ๊ฒ์
๋๋ค ... ๊ฑฐ์ ๋ชจ๋ ๊ฒ์ด ์ ์ ์ผ๋ก ์
๋ ฅ๋ฉ๋๋ค. ์ธ์ด์๋ Java, C#, C, Rust, F#, Go ๋ฑ์ ์ ์ ์ ํ์ด ์์ต๋๋ค.
์๋ฅผ ๋ค์ด C#์์ TypeScript๋ก ์์ฑ๋ npm ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํธ์ถํ๋ ค๋ ๊ฒฝ์ฐ TypeScript ์ ์๋ฅผ ์ฌ์ฉํ๊ณ C#์์ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ง๋ง ๋ฌธ์ ๋ number
์ ํ์ด float
๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํ์ง ์๊ณ C#์์ ๋ฐฐ์ด์ ์ธ๋ฑ์ฑํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ธฐํ ์ฌ์ฉ ์ฌ๋ก: ์ธ์ด ๊ฐ ๋ณํ ์ฉ์ด์ฑ, ์ฑ๋ฅ ์ต์ ํ ๋ฑ
์ด๊ฒ์ด ์ ์ฉํ ๋ ํ๋์ ๊ฒฝ์ฐ๋ ๋งค์ฐ ๋ช ์์ ์ธ ๋ณ๋์ ์ซ์ ์ ํ์ด ์๋ WebAssembly์์ ์ํธ ์์ฉ์ ๋๋ค(C# ์ฌ์ฉ ์ฌ๋ก๋ก ๊ฐ๋ตํ๊ฒ ์ธ๊ธ๋์์ง๋ง ๊ทธ๋ณด๋ค ํจ์ฌ ๋ ๊ด๋ฒ์ํ๊ฒ ์ ์ฉ๋๋ค๋ ์ ์ ๋ถ๋ช ํ ํ๊ณ ์ถ์์ต๋๋ค).
UPD: Nvm, Github์ด "์จ๊ฒจ์ง ํญ๋ชฉ"์ผ๋ก "์ ์ฉํ๊ฒ" ์จ๊ธด https://github.com/microsoft/TypeScript/issues/15480#issuecomment -365420315์์ ์ธ๊ธ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค.
+1
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด ์์ด๋์ด๋ ๋ฌธ์๋ก ํ์ฅํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด
"b".."d"
๋"b" | "c" | "d"
์ ๋๋ค. ๋ฌธ์ ์งํฉ์ ์ง์ ํ๋ ๊ฒ์ด ๋ ์ฌ์ธ ๊ฒ์ ๋๋ค.