Last active
February 29, 2024 21:31
-
-
Save zachhardesty7/b1d6650475c0b30dc57eebe13d20ae37 to your computer and use it in GitHub Desktop.
TS: isTruthy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copyright 2023 Zach Hardesty | |
// want to check this out in the TypeScript playground? | |
// visit the following link to automatically see the latest version! | |
// https://www.typescriptlang.org/play?jsx=0#gist/b1d6650475c0b30dc57eebe13d20ae37 | |
/** | |
* Type guard helper for checking if a value is truthy. mostly for use with | |
* {@link Array.prototype.filter} to clean up array types | |
* | |
* @example | |
* const foo = true | |
* const bar = false | |
* const baz = [foo && "string1", bar && "string2"] | |
* console.log(baz.filter(isTruthy)) | |
* // => ["string1"] | |
* // boolean is removed from type of baz and it becomes string[] | |
* | |
* @param input - Value to check | |
* @see https://stackoverflow.com/a/19839953/5299167 for a list of falsey values | |
*/ | |
function isTruthy<T>( | |
input: T, | |
): input is T extends undefined | null | false | "" | 0 | 0n ? never : T { | |
return !!input; | |
} | |
const x0_0 = ([true, false] as const).filter(isTruthy); | |
type T0_0 = Expect<typeof x0_0, true[]>; | |
const x1_0 = ([1, 0, 0.0, -0, 0x0] as const).filter(isTruthy); | |
type T1_0 = Expect<typeof x1_0, 1[]>; | |
const x2_0 = ([{}, undefined, null] as const).filter(isTruthy); | |
type T2_0 = Expect<typeof x2_0, {}[]>; | |
const x3_0 = (["truthy", "", ``] as const).filter(isTruthy); | |
type T3_0 = Expect<typeof x3_0, "truthy"[]>; | |
const x4_0 = ([1n, 0n, 0x0n] as const).filter(isTruthy); | |
type T4_0 = Expect<typeof x4_0, 1n[]>; | |
const x5_0 = ([0, false] as const).filter(isTruthy); | |
type T5_0 = Expect<typeof x5_0, never[]>; | |
const x6_0 = ([true, NaN, Number.NaN] as const).filter(isTruthy); | |
// @ts-expect-error - no literal type for NaN, so impossible to remove `number` from result type | |
type T6_0 = Expect<typeof x6_0, true[]>; | |
const x7_0 = ([] as never[]).filter(isTruthy); | |
type T7_0 = Expect<typeof x7_0, never[]>; | |
const v010 = Math.random() > 0.5 ? "a" : undefined; | |
if (isTruthy(v010)) { | |
type T010 = Expect<typeof v010, "a">; | |
} else { | |
type T010 = Expect<typeof v010, undefined>; | |
} | |
const v020 = Math.random() > 0.5 ? "a" : false; | |
if (isTruthy(v020)) { | |
type T020 = Expect<typeof v020, "a">; | |
} else { | |
type T020 = Expect<typeof v020, false>; | |
} | |
const v030 = Math.random() > 0.5 ? "a" : Math.random() > 0.5 ? "" : false; | |
if (isTruthy(v030)) { | |
type T030 = Expect<typeof v030, "a">; | |
} else { | |
type T030 = Expect<typeof v030, false | "">; | |
} | |
type Result = "ACK" | "ERR" | ""; | |
declare const result: Result; | |
if (result) { | |
console.log("🚀 ~ result:", result); | |
// handle that a result was received | |
} else { | |
console.log("🚀 ~ result:", result); | |
// couldn't get a result | |
} | |
/** @see https://gist.github.com/zachhardesty7/1b5b6f6de328f1bb7c78cbe96ba5c720 */ | |
type Expect< | |
TInput extends TIntersect, | |
TExpected extends TIntersect, | |
TIntersect = TExpected & TInput, | |
> = TInput; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment