Created
January 24, 2026 06:32
-
-
Save gutchom/7760fb360077f75af693f9a03a01960f to your computer and use it in GitHub Desktop.
TypeScriptで等差数列型を作った
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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