@@ -177,8 +177,8 @@ export type ObjectOf<T extends RecordOf<Predicate<unknown>>> = FlatType<
177
177
* };
178
178
* const a: unknown = { a: 0, b: "a" };
179
179
* 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;
182
182
* }
183
183
* ```
184
184
*/
@@ -255,9 +255,7 @@ export function isSymbol(x: unknown): x is symbol {
255
255
return typeof x === "symbol" ;
256
256
}
257
257
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 ;
261
259
262
260
/**
263
261
* 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)[]
266
264
* import is from "./is.ts";
267
265
*
268
266
* const preds = [is.Number, is.String, is.Boolean];
269
- * const a: unknown = { a: 0, b: "a", c: true } ;
267
+ * const a: unknown = 0 ;
270
268
* if (is.OneOf(preds)(a)) {
271
- * // a is narrowed to number | string | boolean;
269
+ * // a is narrowed to number | string | boolean
272
270
* const _: number | string | boolean = a;
273
271
* }
274
272
* ```
@@ -279,6 +277,32 @@ export function isOneOf<T extends readonly Predicate<unknown>[]>(
279
277
return ( x : unknown ) : x is OneOf < T > => preds . some ( ( pred ) => pred ( x ) ) ;
280
278
}
281
279
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
+
282
306
export type OptionalPredicate < T > = Predicate < T | undefined > & {
283
307
optional : true ;
284
308
} ;
@@ -291,7 +315,7 @@ export type OptionalPredicate<T> = Predicate<T | undefined> & {
291
315
*
292
316
* const a: unknown = "a";
293
317
* if (is.OptionalOf(is.String)(a)) {
294
- * // a is narrowed to string | undefined;
318
+ * // a is narrowed to string | undefined
295
319
* const _: string | undefined = a;
296
320
* }
297
321
* ```
@@ -323,5 +347,6 @@ export default {
323
347
Nullish : isNullish ,
324
348
Symbol : isSymbol ,
325
349
OneOf : isOneOf ,
350
+ AllOf : isAllOf ,
326
351
OptionalOf : isOptionalOf ,
327
352
} ;
0 commit comments