@@ -82,6 +82,39 @@ export function isTupleOf<T extends readonly Predicate<unknown>[]>(
8282 } ;
8383}
8484
85+ // https://stackoverflow.com/a/71700658/1273406
86+ export type UniformTupleOf <
87+ T ,
88+ N extends number ,
89+ R extends readonly T [ ] = [ ] ,
90+ > = R [ "length" ] extends N ? R : UniformTupleOf < T , N , readonly [ T , ...R ] > ;
91+
92+ /**
93+ * Return a type predicate function that returns `true` if the type of `x` is `UniformTupleOf<T>`.
94+ *
95+ * ```ts
96+ * import is from "./is.ts";
97+ *
98+ * const a: unknown = [0, 1, 2, 3, 4];
99+ * if (is.UniformTupleOf(5)(a)) {
100+ * // a is narrowed to [unknown, unknown, unknown, unknown, unknown]
101+ * const _: readonly [unknown, unknown, unknown, unknown, unknown] = a;
102+ * }
103+ *
104+ * if (is.UniformTupleOf(5, is.Number)(a)) {
105+ * // a is narrowed to [number, number, number, number, number]
106+ * const _: readonly [number, number, number, number, number] = a;
107+ * }
108+ * ```
109+ */
110+ export function isUniformTupleOf < T , N extends number > (
111+ n : N ,
112+ pred : Predicate < T > = ( _x : unknown ) : _x is T => true ,
113+ ) : Predicate < UniformTupleOf < T , N > > {
114+ const predTup = Array ( n ) . fill ( pred ) ;
115+ return isTupleOf ( predTup ) as Predicate < UniformTupleOf < T , N > > ;
116+ }
117+
85118/**
86119 * Synonym of `Record<string | number | symbol, T>`
87120 */
@@ -248,6 +281,7 @@ export default {
248281 Array : isArray ,
249282 ArrayOf : isArrayOf ,
250283 TupleOf : isTupleOf ,
284+ UniformTupleOf : isUniformTupleOf ,
251285 Record : isRecord ,
252286 RecordOf : isRecordOf ,
253287 ObjectOf : isObjectOf ,
0 commit comments