@danwithabox/nullish
Version:
Utilities that pair well with the lovely nullish coalescing (??) operator
1 lines • 3.52 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/nullish-map.ts","../src/nullish-of.ts"],"sourcesContent":["export * from \"./nullish-map\";\nexport * from \"./nullish-of\";\n","/**\n * Map a nullish value as if it were non-nullish.\n *\n * The result retains either `null`, or `undefined`, or both, or neither, depending on what's inferred from the input value.\n *\n * Practically, the possible mappings are:\n *\n * ---\n *\n * `T | null | undefined` => `R | null | undefined`\n * ```ts\n * const val = 0 as number | null | undefined;\n * const res = nullishMap(val, val => `${val}`);\n * // ^ string | null | undefined\n * ```\n *\n * ---\n *\n * `T | undefined` => `R | undefined`\n * ```ts\n * const val = 0 as number | undefined;\n * const res = nullishMap(val, val => `${val}`);\n * // ^ string | undefined\n * ```\n *\n * ---\n *\n * `T | null` => `R | null`\n * ```ts\n * const val = 0 as number | null;\n * const res = nullishMap(val, val => `${val}`);\n * // ^ string | null\n * ```\n *\n * ---\n *\n * `T` => `R` _(not terribly useful, but it's allowed for simplicity's sake)_\n * ```ts\n * const val = 0 as number;\n * const res = nullishMap(val, val => `${val}`);\n * // ^ string\n * ```\n *\n */\nexport function nullishMap<T, R>(value: T, mapFn: (value: NonNullable<T>) => R): NullishMap<T, R> {\n if ((value !== null) && (value !== void 0)) return mapFn(value) as NullishMap<T, R>;\n return value as NullishMap<T, R>;\n}\n/**\n * Union of `R`, and either `null`, `undefined`, or both, depending on which of the two are constituents of `T`.\n *\n * @see {@link nullishMap}\n */\nexport type NullishMap<T, R> = T extends null ? null : T extends undefined ? undefined : R;\n","/**\n * Augment a value's type with `null` and `undefined`.\n *\n * Zero performance impact at runtime, as it is simply an identity function, and it most likely gets inlined.\n *\n * Useful in a few common situations:\n *\n * ---\n *\n * Making an inferred type optional at variable declaration, since something like https://github.com/microsoft/TypeScript/issues/13321 is not yet possible:\n * ```ts\n * let optional = nullishOf({ foo: 1, bar: 2, }) ?? void 0;\n * // ^ { foo: number; bar: number; } | undefined\n * ```\n * ---\n * Safely accessing arrays without enabling `noUncheckedIndexedAccess` in `tsconfig.json`:\n * ```ts\n * const myArray = [0, , 2].map(n => Boolean(n));\n *\n * // Without `noUncheckedIndexedAccess`:\n * let element = myArray[1];\n * // ^ `boolean`\n * // this is incorrect, due to the empty element\n *\n * // With manual typing:\n * let maybeElement1 = myArray[1] as undefined | (typeof myArray)[number];\n * // ^ `boolean | undefined`\n * // correct, but a hassle to type\n *\n * // With `nullishOf`:\n * let maybeElement2 = nullishOf(myArray[1]);\n * // ^ `boolean | null | undefined`\n * // correct enough: it has an extraneous `null`, but that's fine in most situations\n *\n * // And if you want to narrow to either `null` or `undefined`:\n * let maybeElement3 = nullishOf(myArray[1]) ?? null;\n * // ^ `boolean | null`\n * // correct\n * let maybeElement4 = nullishOf(myArray[1]) ?? void 0;\n * // ^ `boolean | undefined`\n * // correct\n * ```\n */\nexport function nullishOf<T>(value: T): T | null | undefined {\n return value;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC4CO,SAAS,WAAiB,OAAU,OAAuD;AAC9F,MAAK,UAAU,QAAU,UAAU,OAAS,QAAO,MAAM,KAAK;AAC9D,SAAO;AACX;;;ACJO,SAAS,UAAa,OAAgC;AACzD,SAAO;AACX;","names":[]}