type-plus
Version:
Provides additional types for TypeScript.
68 lines (60 loc) • 1.93 kB
text/typescript
import type { IsEqual } from '../equal/equal.js'
import type { CanAssign } from '../index.js'
import type { Tail } from '../tuple/tail.js'
import type { UnionOfValues } from './union_of_values.js'
/**
* Determines whether the array type `A` contains any elements that satisfies the specified `Criteria` type.
*
* It operates in `loose` mode by default,
* which means literal types satisfies their widened counterparts.
*
* You can also change it to `strict` mode.
*
* 🦴 *utilities*
*
* @example
* ```ts
* Some<string[], string> // true
* Some<['a', boolean], boolean> // true
* Some<['a', true], boolean> //true
*
* Some<['a', true], boolean, 'strict'> // false
* ```
*/
export type Some<
A extends any[],
Criteria,
Mode extends 'strict' | 'loose' = 'loose',
Then = true,
Else = false
> = Mode extends 'strict' ? Some.Strict<A, Criteria, Then, Else> : Some.Loose<A, Criteria, Then, Else>
export namespace Some {
export type Strict<A extends unknown[], Criteria, Then, Else> = number extends A['length']
? StrictArray<A, Criteria, Then, Else>
: StrictTuple<A, Criteria, Then, Else>
export type StrictArray<A extends unknown[], Criteria, Then, Else> = IsEqual<
UnionOfValues<A>,
Criteria,
Then,
Else
>
export type StrictTuple<A extends unknown[], Criteria, Then, Else> = A['length'] extends 0
? Else
: IsEqual<A[0], Criteria> extends true
? Then
: StrictTuple<Tail<A>, Criteria, Then, Else>
export type Loose<A extends unknown[], Criteria, Then, Else> = number extends A['length']
? LooseArray<A, Criteria, Then, Else>
: LooseTuple<A, Criteria, Then, Else>
export type LooseArray<A extends unknown[], Criteria, Then, Else> = CanAssign<
UnionOfValues<A>,
Criteria,
Then,
Else
>
export type LooseTuple<A extends unknown[], Criteria, Then, Else> = A['length'] extends 0
? Else
: A[0] extends Criteria
? Then
: LooseTuple<Tail<A>, Criteria, Then, Else>
}