Skip to content

Instantly share code, notes, and snippets.

@gutchom
Created January 24, 2026 06:32
Show Gist options
  • Select an option

  • Save gutchom/7760fb360077f75af693f9a03a01960f to your computer and use it in GitHub Desktop.

Select an option

Save gutchom/7760fb360077f75af693f9a03a01960f to your computer and use it in GitHub Desktop.
TypeScriptで等差数列型を作った
type Len<T extends unknown[]> = T extends { length: infer U extends number }
? U
: never;
type Seq<T extends number, U extends number[] = []> = U["length"] extends T
? U
: Seq<T, [...U, U["length"]]>;
let seq: Seq<990>;
// 0から9までのUnion型
type Digits = Seq<10>[number];
type Tuple<
N extends number,
T = unknown,
U extends T[] = [],
> = U["length"] extends N ? U : Tuple<N, T, [...U, T]>;
let tuple: Tuple<990>;
// 加算
export type Inc<A extends number, B extends number> = Len<
[...Tuple<A>, ...Tuple<B>]
>;
let inc: Inc<1, 2>; // 3
// 減算
export type Dec<A extends number, B extends number> =
Tuple<A> extends [...Tuple<B>, ...infer Rest] ? Rest["length"] : Dec<B, A>;
let dec01: Dec<0, 1>; // 1
let dec20: Dec<5, 3>; // 2
// 合算
export type Sum<T extends number[]> = T extends [
infer A extends number,
infer B extends number,
...infer Rest extends number[],
]
? Sum<[Inc<A, B>, ...Rest]>
: T["length"] extends 1
? T[0]
: never;
let sum: Sum<[]>; // never
let sum12: Sum<[1, 2]>; // 3
let sum246: Sum<[2, 4, 6]>; // 12
// 乗算
export type Mul<A extends number, B extends number> = Sum<Tuple<A, B>>;
let mul: Mul<2, 3>; // 6
export type Reverse<
T extends unknown[],
U extends unknown[] = [],
> = T["length"] extends 0
? never
: U["length"] extends T["length"]
? U
: Reverse<T, [T[U["length"]], ...U]>;
let reverse: Reverse<[1, 2, 3]>;
// 等差数列
type ArithmeticSequence<
Init extends number,
Diff extends number,
Count extends number,
Sequence extends number[] = [Init],
Previous extends number = Sequence[0],
> = Sequence["length"] extends Count
? Reverse<Sequence>
: ArithmeticSequence<Init, Diff, Count, [Inc<Diff, Previous>, ...Sequence]>;
let foo: ArithmeticSequence<0, 1, 450>;
let hoge: ArithmeticSequence<2, 2, 400>;
let fuga: ArithmeticSequence<3, 3, 300>;
// 等比数列
type GeometricSequence<
Init extends number,
Ratio extends number,
Count extends number,
Sequence extends number[] = [Init],
> = Init extends 0
? never
: Ratio extends 0
? never
: Ratio extends 1
? never
: Sequence["length"] extends Count
? Reverse<Sequence>
: GeometricSequence<
Init,
Ratio,
Count,
[Sum<Tuple<Ratio, Sequence[0]>>, ...Sequence]
>;
let geoseq: GeometricSequence<2, 3, 10>;
export type Parse<N extends string> =
`${N}` extends `${infer M extends number}${number}` ? M : never;
let parse: Parse<123>;
export type Figures<N extends number> = `${N}`["length"];
export type Tail<N extends number> =
`${N}` extends `${number}${infer M extends Digits}` ? M : never;
let tail: Tail<123>;
type Odd<N extends number> = Tail<N> extends 1 | 3 | 5 | 7 | 9 ? true : false;
type Even<N extends number> = Tail<N> extends 0 | 2 | 4 | 6 | 8 ? true : false;
var odd: Odd<123>;
var even: Even<123>;
export type IsOdd<T extends number> = `${T}`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment