指定した範囲の整数値を取る型をつくりたい

やりたいこと

例えば1 ~ 100の任意の整数値を取る型を作りたい

// イメージ
type Range100 = Range<1, 100>

const test: Range100 = 100; // ok
const test1: Range100 = 1; // ok
const test2: Range100 = 101; // ng

解決策

type-festというライブラリのIntRangeに解決策があります。実装を確認すると、StartとEndを指定してEndになるまで再帰的に処理しています。

もう少し簡潔な方法で実装している方もいらっしゃいます。

qiita.com

この程度であればライブラリの実装を移植すれば良さそうですが、自分で思いつくには難しい。

うまくいかないやり方

const array = [];
for (let i = 1; i < 101; i++) {
  array.push(i);
}

type Range100 = typeof array[number];
const test2: Range100 = 101;

解決策のやり方が難しいと思うと、こういうわかりやすい方法にしたくなりますが、この方法はうまくいきません。arrayの内容が実行時に決まるので、コンパイル時に行われるTypeScriptの型推論が効かずRange100はnumber型として推論されます。

同様の理由で以下もうまくいきません。

const array: number[] = Array.from({ length: 100 }, (_, i) => i + 1);

type Range100 = typeof array[number];
const test1: Range100 = 101;

もちろんうまくいくやり方

type Range100 = 1 | 2 | 3 | 4 | 5 | 6 ...() | 100

あるいはコンパイル時に値が決まる

const range = [1,2,3,4, ...(), 100] as const;
type Range100 = typeof range[number]

も当然OKです。後者はUnion Typeを作る際によく使いますね。

Ruby範囲演算子があれば良いのですが。
なにか良い方法はないものでしょうか。