Typescript: ์ œ์•ˆ: ์ˆซ์ž ์œ ํ˜•์˜ ๋ฒ”์œ„

์— ๋งŒ๋“  2017๋…„ 04์›” 30์ผ  ยท  106์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: microsoft/TypeScript

์œ ํ˜•์„ ์ •์˜ํ•  ๋•Œ | ๊ตฌ๋ถ„๋œ ์—ฌ๋Ÿฌ ์ˆซ์ž๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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
}
In Discussion Suggestion

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด ์•„์ด๋””์–ด๋Š” ๋ฌธ์ž๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "b".."d" ๋Š” "b" | "c" | "d" ์ž…๋‹ˆ๋‹ค. ๋ฌธ์ž ์ง‘ํ•ฉ์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” ์‰ฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  106 ๋Œ“๊ธ€

์ด ์•„์ด๋””์–ด๋Š” ๋ฌธ์ž๋กœ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "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 ๋“ฑ์˜ ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์–ธ์–ด์˜ ์‚ฌ๋žŒ๋“ค์€ ์ •์  ์ •์˜์™€ ๋Ÿฐํƒ€์ž„ ๋™์ž‘์˜ ์ฐจ์ด๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  • ์ œ์•ˆํ•œ ๊ตฌ๋ฌธ์€ ํ•˜ํ•œ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. 0์ด ์•„๋‹ˆ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?
  • ์ด๋ฏธ ES2016์— ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฏ€๋กœ ์•ฐ๋น„์–ธํŠธ/์œ ํ˜• ์ปจํ…์ŠคํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ง€์ˆ˜ ์—ฐ์‚ฐ์ž๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ฃผ์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ ํ˜• ์‹œ์Šคํ…œ ํŠœ๋ง์„ ์™„๋ฃŒํ•˜๊ณ  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 ์ฐธ์กฐ

__์‚ฌ์šฉ ์‚ฌ๋ก€:__

  1. TypeScript์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์ด WebAssembly ๋˜๋Š” ๋‹ค๋ฅธ ๋Œ€์ƒ์œผ๋กœ ์ปดํŒŒ์ผ๋  ์ˆ˜ ์žˆ๋„๋ก ์ •ํ™•ํ•œ int ์œ ํ˜•์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” UInt8Array , Int8Array , Uint16Array ๋“ฑ์ž…๋‹ˆ๋‹ค. TypeScript์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ฑฐ๋‚˜ ์“ธ ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const ab = new ArrayBuffer(1e3);
const uint8 = new UInt8Array(ab);

uint8[0] = 0xFFFFFFFF; // TSError: Number too big!
  1. ๋‚ด OP์—์„œ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

  2. ์ด๊ฒƒ์„ ๊ตฌํ˜„ํ•˜๋ฉด 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


GtEq ์œ ํ˜•; (>= x)

  • (>= Infinity) = Infinity
  • (>= -Infinity) = -Infinity|double|Infinity
  • Infinity ๋Š” (>= [finite-literal]) ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (>= [finite-literal]) ๋Š” double|Infinity ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (>= NaN) = never
  • (>= int) = (>= -9007199254740991)
  • (>= double) = (>= -1.7976931348623157e+308)
  • (>= number) = number

GT ์œ ํ˜•; (> x)

  • (> Infinity) = never
  • (> -Infinity) = double|Infinity
  • Infinity ๋Š” (> [finite-literal]) ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (> [finite-literal]) ๋Š” double|Infinity ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (> NaN) = never
  • (> int) = (> -9007199254740991)
  • (> double) = (> -1.7976931348623157e+308)
  • (> number) = number

LtEq ์œ ํ˜•; (<= x)

  • (<= Infinity) = -Infinity|double|Infinity
  • (<= -Infinity) = -Infinity
  • -Infinity ๋Š” (<= [finite-literal]) ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (<= [finite-literal]) ๋Š” -Infinity|double ์˜ ํ•˜์œ„ ์œ ํ˜•์ž…๋‹ˆ๋‹ค.
  • (<= NaN) = never
  • (<= int) = (<= 9007199254740991)
  • (<= double) = (<= 1.7976931348623157e+308)
  • (<= number) = number

Lt ์œ ํ˜•; (< 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 ์œ ํ˜•

๋‘ 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 ์œ ํ˜•

๋‘ 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 ์œ ํ˜•

๋‘ 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 ์œ ํ˜•

๋‘ 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 ์ฝ”๋“œ ํ˜ธ๋ฒ„ ํžŒํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜ธ๋ฒ„ ํžŒํŠธ์˜ ์ˆซ์ž๋Š” ๋ฌด์ž‘์œ„๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.

image

์Šฌํ”„๊ฒŒ๋„ ์•ฝ 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

์ด๋ฅผ ์™„๋ฃŒํ•˜๋ ค๋ฉด ์ผ๋ถ€ ๊ฒฝ์šฐ์— ๋™์ž‘์„ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  1. Range<T, T> === T ์ •์˜
  2. Range<5, 1> === NaN ์ •์˜
  3. Range<NaN, T> === Range<T, NaN> === NaN ๊ฐ™์€ ๊ฐ’์€ ์กด์žฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  4. Range<1 | 2, 5> === Range<2, 5> ์ฒซ ๋ฒˆ์งธ ์œ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋” ํฐ ์ˆซ์ž์˜ ๊ฐ€๋Šฅ์„ฑ์€ ๋ฒ”์œ„๋ฅผ ๋” ์งง๊ฒŒ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
  5. Range<1, 4 | 5> === Range<1, 4> ๋‘ ๋ฒˆ์งธ ์œ ํ˜• ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋‚ฎ์€ ์ˆซ์ž์˜ ๊ฐ€๋Šฅ์„ฑ์€ ๋ฒ”์œ„๋ฅผ ๋” ์งง๊ฒŒ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.
  6. 1.5 extends Range<1, 2> ๋Š” ์ •์˜์ƒ true์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  7. Range<Range<A, B>, C> === NaN extends Range<A, B> ? NaN : Range<B, C> ๋Š” 5์™€ 3์— ์ด์–ด์ง‘๋‹ˆ๋‹ค.
  8. 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

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰