@@ -177,8 +177,8 @@ export type ObjectOf<T extends RecordOf<Predicate<unknown>>> = FlatType<
177177 * };
178178 * const a: unknown = { a: 0, b: "a" };
179179 * if (is.ObjectOf(predObj)(a)) {
180- * // a is narrowed to { a: number, b: string, c?: boolean }
181- * const _: { a: number, b: string, c?: boolean } = a;
180+ * // a is narrowed to { a: number; b: string; c?: boolean }
181+ * const _: { a: number; b: string; c?: boolean } = a;
182182 * }
183183 * ```
184184 */
@@ -255,9 +255,7 @@ export function isSymbol(x: unknown): x is symbol {
255255 return typeof x === "symbol" ;
256256}
257257
258- export type OneOf < T > = T extends ( infer U ) [ ]
259- ? T extends Predicate < infer U > [ ] ? U : T
260- : T ;
258+ export type OneOf < T > = T extends Predicate < infer U > [ ] ? U : never ;
261259
262260/**
263261 * Return a type predicate function that returns `true` if the type of `x` is `OneOf<T>`.
@@ -266,9 +264,9 @@ export type OneOf<T> = T extends (infer U)[]
266264 * import is from "./is.ts";
267265 *
268266 * const preds = [is.Number, is.String, is.Boolean];
269- * const a: unknown = { a: 0, b: "a", c: true } ;
267+ * const a: unknown = 0 ;
270268 * if (is.OneOf(preds)(a)) {
271- * // a is narrowed to number | string | boolean;
269+ * // a is narrowed to number | string | boolean
272270 * const _: number | string | boolean = a;
273271 * }
274272 * ```
@@ -279,6 +277,32 @@ export function isOneOf<T extends readonly Predicate<unknown>[]>(
279277 return ( x : unknown ) : x is OneOf < T > => preds . some ( ( pred ) => pred ( x ) ) ;
280278}
281279
280+ type UnionToIntersection < U > =
281+ ( U extends unknown ? ( k : U ) => void : never ) extends ( ( k : infer I ) => void )
282+ ? I
283+ : never ;
284+ export type AllOf < T > = UnionToIntersection < OneOf < T > > ;
285+
286+ /**
287+ * Return a type predicate function that returns `true` if the type of `x` is `AllOf<T>`.
288+ *
289+ * ```ts
290+ * import is from "./is.ts";
291+ *
292+ * const preds = [is.ObjectOf({ a: is.Number }), is.ObjectOf({ b: is.String })];
293+ * const a: unknown = { a: 0, b: "a" };
294+ * if (is.AllOf(preds)(a)) {
295+ * // a is narrowed to { a: number; b: string }
296+ * const _: { a: number; b: string } = a;
297+ * }
298+ * ```
299+ */
300+ export function isAllOf < T extends readonly Predicate < unknown > [ ] > (
301+ preds : T ,
302+ ) : Predicate < AllOf < T > > {
303+ return ( x : unknown ) : x is AllOf < T > => preds . every ( ( pred ) => pred ( x ) ) ;
304+ }
305+
282306export type OptionalPredicate < T > = Predicate < T | undefined > & {
283307 optional : true ;
284308} ;
@@ -291,7 +315,7 @@ export type OptionalPredicate<T> = Predicate<T | undefined> & {
291315 *
292316 * const a: unknown = "a";
293317 * if (is.OptionalOf(is.String)(a)) {
294- * // a is narrowed to string | undefined;
318+ * // a is narrowed to string | undefined
295319 * const _: string | undefined = a;
296320 * }
297321 * ```
@@ -323,5 +347,6 @@ export default {
323347 Nullish : isNullish ,
324348 Symbol : isSymbol ,
325349 OneOf : isOneOf ,
350+ AllOf : isAllOf ,
326351 OptionalOf : isOptionalOf ,
327352} ;
0 commit comments