Skip to content

Commit

Permalink
Improve TruthConvert accuracy
Browse files Browse the repository at this point in the history
  • Loading branch information
wagenet committed Sep 11, 2023
1 parent e7fe699 commit f467900
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
11 changes: 7 additions & 4 deletions packages/ember-truth-helpers/src/utils/truth-convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ export type Falsy =
| ''
| never[];

type ConvertTruthyObject<T> = T extends { isTruthy: infer U } ? U : T;

// We check here in the order of the following function to maintain parity
// Note that this will not handle EmberArray correctly.
// We don't use Falsy since we want to be able to more definitively determine
// truthy results.
type _TruthConvert<T> = T extends { isTruthy: true }
export type TruthConvert<T> = T extends { isTruthy: true }
? true
: T extends { isTruthy: false }
? false
Expand All @@ -30,14 +28,20 @@ type _TruthConvert<T> = T extends { isTruthy: true }
: T extends number
? T extends 0 | -0
? false
: number extends T
? boolean
: true
: T extends bigint
? T extends 0n
? false
: bigint extends T
? boolean
: true
: T extends string
? T extends ''
? false
: string extends T
? boolean
: true
: T extends never[]
? false
Expand All @@ -46,7 +50,6 @@ type _TruthConvert<T> = T extends { isTruthy: true }
: T extends object
? true
: boolean;
export type TruthConvert<T> = _TruthConvert<ConvertTruthyObject<T>>;

export type MaybeTruthy =
| { isTruthy: boolean }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@ expectTypeOf<TruthConvert<undefined>>().toEqualTypeOf<false>();

expectTypeOf<TruthConvert<true>>().toEqualTypeOf<true>();
expectTypeOf<TruthConvert<false>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<boolean>>().toEqualTypeOf<boolean>();

expectTypeOf<TruthConvert<0>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<-0>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<0n>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<1>>().toEqualTypeOf<true>();
expectTypeOf<TruthConvert<number>>().toEqualTypeOf<boolean>();
expectTypeOf<TruthConvert<0n>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<1n>>().toEqualTypeOf<true>();
expectTypeOf<TruthConvert<bigint>>().toEqualTypeOf<boolean>();

expectTypeOf<TruthConvert<''>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<'A String'>>().toEqualTypeOf<true>();
expectTypeOf<TruthConvert<string>>().toEqualTypeOf<boolean>();

expectTypeOf<TruthConvert<{ foo: 1; isTruthy: true }>>().toEqualTypeOf<true>();
expectTypeOf<
TruthConvert<{ foo: 1; isTruthy: false }>
>().toEqualTypeOf<false>();
// isTruthy isn't a boolean but we still have a real object so it's truthy
expectTypeOf<TruthConvert<{ foo: 1; isTruthy: 1 }>>().toEqualTypeOf<true>();
expectTypeOf<TruthConvert<{ isTruthy: boolean }>>().toEqualTypeOf<boolean>();

expectTypeOf<TruthConvert<never[]>>().toEqualTypeOf<false>();
expectTypeOf<TruthConvert<string[]>>().toEqualTypeOf<boolean>();
Expand All @@ -30,6 +36,9 @@ expectTypeOf<
TruthConvert<never[] & { isTruthy: true }>
>().toEqualTypeOf<true>();

expectTypeOf<TruthConvert<1 | false>>().toEqualTypeOf<boolean>();
expectTypeOf<TruthConvert<0 | false>>().toEqualTypeOf<false>();

expectTypeOf(truthConvert(null)).toEqualTypeOf<false>();
expectTypeOf(truthConvert(undefined)).toEqualTypeOf<false>();

Expand Down

0 comments on commit f467900

Please sign in to comment.