Skip to content

Commit

Permalink
fix: update IsNotBigint
Browse files Browse the repository at this point in the history
  • Loading branch information
unional committed Oct 23, 2023
1 parent 68500b5 commit 1b83af4
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 16 deletions.
1 change: 0 additions & 1 deletion type-plus/ts/bigint/is_bigint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ it('can override $never branch', () => {
})

describe('exact mode', () => {

it('returns true for bigint', () => {
testType.true<IsBigint<bigint, { exact: true }>>(true)
})
Expand Down
6 changes: 3 additions & 3 deletions type-plus/ts/bigint/is_bigint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,20 +92,20 @@ export namespace IsBigint {
* This is a type util for building custom types.
* It does not check against special types.
*/
export type $<T, $O extends IsBigint.$Options> =
export type $<T, $O extends $Options> =
$ResolveOptions<[$O['exact'], false]> extends true
? $IsDistributive<$O, { $then: _SD<T, $O>, $else: _SN<T, $O> }>
: Assignable.$<T, bigint, $O>

export type _SD<T, $O extends IsBigint.$Options> =
export type _SD<T, $O extends $Options> =
T extends bigint
? (
`${T}` extends `${number}`
? $ResolveBranch<T, $O, [$Else]>
: $ResolveBranch<T, $O, [$Then]>
)
: $ResolveBranch<T, $O, [$Else]>
export type _SN<T, $O extends IsBigint.$Options> = (
export type _SN<T, $O extends $Options> = (
[bigint, T] extends [T, bigint]
? (T extends bigint
? (`${T}` extends `${number}`
Expand Down
100 changes: 93 additions & 7 deletions type-plus/ts/bigint/is_not_bigint.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { it } from '@jest/globals'
import { describe, it } from '@jest/globals'

import { type $Any, type $BranchOptions, type $Else, type $Never,type $Then, type $Unknown, type IsNotBigint, testType } from '../index.js'
import { testType, type $Any, type $BranchOptions, type $Else, type $Never, type $Then, type $Unknown, type IsNotBigint } from '../index.js'

it('returns false for bigint', () => {
testType.false<IsNotBigint<bigint>>(true)
Expand Down Expand Up @@ -40,11 +40,6 @@ it('distributes over union type', () => {
testType.equal<IsNotBigint<bigint | 1>, boolean>(true)
})

it('can disable union distribution', () => {
testType.equal<IsNotBigint<1n | 1>, boolean>(true)
testType.equal<IsNotBigint<1n | 1, { distributive: false }>, true>(true)
})

it('returns false for intersection type', () => {
testType.false<IsNotBigint<bigint & { a: 1 }>>(true)
})
Expand All @@ -59,6 +54,11 @@ it('works as filter', () => {
testType.equal<IsNotBigint<string | 1n, { selection: 'filter' }>, string>(true)
})

it('can disable union distribution', () => {
testType.equal<IsNotBigint<1n | 1>, boolean>(true)
testType.equal<IsNotBigint<1n | 1, { distributive: false }>, true>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotBigint<bigint, IsNotBigint.$Branch>, $Else>(true)
testType.equal<IsNotBigint<1n, IsNotBigint.$Branch>, $Else>(true)
Expand Down Expand Up @@ -91,3 +91,89 @@ it('can override $never branch', () => {
testType.equal<IsNotBigint<never>, true>(true)
testType.equal<IsNotBigint<never, { $never: unknown }>, unknown>(true)
})

describe('exact mode', () => {
it('returns false for bigint', () => {
testType.false<IsNotBigint<bigint, { exact: true }>>(true)
})

it('returns true if T is bigint literals', () => {
testType.true<IsNotBigint<0n, { exact: true }>>(true)
testType.true<IsNotBigint<1n, { exact: true }>>(true)
})

it('returns true for special types', () => {
testType.true<IsNotBigint<any, { exact: true }>>(true)
testType.true<IsNotBigint<unknown, { exact: true }>>(true)
testType.true<IsNotBigint<void, { exact: true }>>(true)
testType.true<IsNotBigint<never, { exact: true }>>(true)
})

it('returns true for other types', () => {
testType.true<IsNotBigint<undefined, { exact: true }>>(true)
testType.true<IsNotBigint<null, { exact: true }>>(true)
testType.true<IsNotBigint<boolean, { exact: true }>>(true)
testType.true<IsNotBigint<true, { exact: true }>>(true)
testType.true<IsNotBigint<false, { exact: true }>>(true)
testType.true<IsNotBigint<number, { exact: true }>>(true)
testType.true<IsNotBigint<1, { exact: true }>>(true)
testType.true<IsNotBigint<string, { exact: true }>>(true)
testType.true<IsNotBigint<'', { exact: true }>>(true)
testType.true<IsNotBigint<symbol, { exact: true }>>(true)
testType.true<IsNotBigint<{}, { exact: true }>>(true)
testType.true<IsNotBigint<string[], { exact: true }>>(true)
testType.true<IsNotBigint<[], { exact: true }>>(true)
testType.true<IsNotBigint<Function, { exact: true }>>(true)
testType.true<IsNotBigint<() => void, { exact: true }>>(true)
})

it('distributes over union type', () => {
testType.equal<IsNotBigint<bigint | 1, { exact: true }>, boolean>(true)
})

it('can disable union distribution', () => {
testType.equal<IsNotBigint<bigint | 1, { distributive: false, exact: true }>, true>(true)
})

it('consider intersection type as strict', () => {
testType.false<IsNotBigint<bigint & { a: 1 }, { exact: true }>>(true)
testType.true<IsNotBigint<1n & { a: 1 }, { exact: true }>>(true)
})

it('works as filter', () => {
testType.equal<IsNotBigint<bigint, { selection: 'filter', exact: true }>, never>(true)

testType.equal<IsNotBigint<never, { selection: 'filter', exact: true }>, never>(true)
testType.equal<IsNotBigint<unknown, { selection: 'filter', exact: true }>, unknown>(true)
testType.equal<IsNotBigint<string | boolean, { selection: 'filter', exact: true }>, string | boolean>(true)

testType.equal<IsNotBigint<string | bigint, { selection: 'filter', exact: true }>, string>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotBigint<bigint, IsNotBigint.$Branch & { exact: true }>, $Else>(true)
testType.equal<IsNotBigint<1n, IsNotBigint.$Branch & { exact: true }>, $Then>(true)

testType.equal<IsNotBigint<any, IsNotBigint.$Branch & { exact: true }>, $Then>(true)
testType.equal<IsNotBigint<unknown, IsNotBigint.$Branch & { exact: true }>, $Then>(true)
testType.equal<IsNotBigint<never, IsNotBigint.$Branch & { exact: true }>, $Then>(true)
testType.equal<IsNotBigint<void, IsNotBigint.$Branch & { exact: true }>, $Then>(true)

testType.equal<IsNotBigint<bigint | 1, IsNotBigint.$Branch & { exact: true }>, $Then | $Else>(true)
})

it('can override $any branch', () => {
testType.equal<IsNotBigint<any, { exact: true }>, true>(true)
testType.equal<IsNotBigint<any, { $any: unknown, exact: true }>, unknown>(true)
})

it('can override $unknown branch', () => {
testType.equal<IsNotBigint<unknown, { exact: true }>, true>(true)
testType.equal<IsNotBigint<unknown, { $unknown: unknown, exact: true }>, unknown>(true)
})

it('can override $never branch', () => {
testType.equal<IsNotBigint<never, { exact: true }>, true>(true)
testType.equal<IsNotBigint<never, { $never: unknown, exact: true }>, unknown>(true)
})
})
64 changes: 59 additions & 5 deletions type-plus/ts/bigint/is_not_bigint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
import type { $SelectInvert } from '../type_plus/branch/$select_invert.js'
import type { $Any } from '../any/any.js'
import type { $Never } from '../never/never.js'
import type { NotAssignable } from '../predicates/not_assignable.js'
import type { $MergeOptions } from '../type_plus/$merge_options.js'
import type { $ResolveOptions } from '../type_plus/$resolve_options.js'
import type { $SpecialType } from '../type_plus/$special_type.js'
import type { $DistributiveOptions } from '../type_plus/branch/$distributive.js'
import type { $Exact } from '../type_plus/branch/$exact.js'
import type { $InputOptions } from '../type_plus/branch/$input_options.js'
import type { $IsDistributive } from '../type_plus/branch/$is_distributive.js'
import type { $ResolveBranch } from '../type_plus/branch/$resolve_branch.js'
import type { $Else, $SelectionBranch, $Then } from '../type_plus/branch/$selection.js'
import type { $SelectionOptions } from '../type_plus/branch/$selection_options.js'
import type { $Unknown } from '../unknown/unknown.js'

/**
* 🎭 *predicate*
Expand Down Expand Up @@ -49,10 +62,51 @@ import type { $SelectInvert } from '../type_plus/branch/$select_invert.js'
* type R = IsNotBigint<bigint, $SelectionBranch> // $Else
* ```
*/
export type IsNotBigint<T, $O extends IsNotBigint.$Options = {}> = $SelectInvert<T, bigint, $O>
export type IsNotBigint<T, $O extends IsNotBigint.$Options = {}> = $SpecialType<T,
$MergeOptions<$O,
{
$then: $ResolveBranch<T, $O, [$Then]>,
$else: IsNotBigint.$<T, $O>
}
>
>

export namespace IsNotBigint {
export type $Options = $SelectInvert.$Options
export type $Default = $SelectInvert.$Default
export type $Branch = $SelectInvert.$Branch
export type $Options = $SelectionOptions &
$DistributiveOptions &
$InputOptions<$Any | $Unknown | $Never> &
$Exact.$Options
export type $Branch<
$O extends $DistributiveOptions & $Exact.$Options = {}
> = $SelectionBranch & $O
/**
* 🧰 *type util*
*
* Validate if `T` is not `bigint` nor `bigint` literals.
*
* This is a type util for building custom types.
* It does not check against special types.
*/
export type $<T, $O extends $Options> =
$ResolveOptions<[$O['exact'], false]> extends true
? $IsDistributive<$O, { $then: _SD<T, $O>, $else: _SN<T, $O> }>
: NotAssignable.$<T, bigint, $O>

export type _SD<T, $O extends $Options> =
T extends bigint
? (
`${T}` extends `${number}`
? $ResolveBranch<T, $O, [$Then]>
: $ResolveBranch<T, $O, [$Else]>
)
: $ResolveBranch<T, $O, [$Then]>
export type _SN<T, $O extends $Options> = (
[bigint, T] extends [T, bigint]
? (T extends bigint
? (`${T}` extends `${number}`
? $ResolveBranch<T, $O, [$Then]>
: $ResolveBranch<T, $O, [$Else]>
)
: $ResolveBranch<T, $O, [$Then]>)
: $ResolveBranch<T, $O, [$Then]>)
}

0 comments on commit 1b83af4

Please sign in to comment.