Skip to content

Instantly share code, notes, and snippets.

@Shrugsy
Shrugsy / objEntries.ts
Last active January 30, 2021 06:33
Allows using `Object.entries` with Typescript while retaining key type information with. Example: https://tsplay.dev/aNnPdW. Note: see discussion here before using this, as keys are intentionally typed as only `string` by design: https://github.com/microsoft/TypeScript/pull/12253
export type Entries<T> = {
[K in keyof T]: [K, T[K]];
}[keyof T][];
/**
* Helper to use `Object.entries` while retaining key type information.
* Input object should be cast `as const` for maximum effectiveness.
*/
export function objEntries<T extends Record<string, unknown>>(obj: T): Entries<T> {
return Object.entries(obj) as Entries<T>;
@Shrugsy
Shrugsy / useStableCallback.ts
Last active November 24, 2022 18:13
React hook that accepts a given callback, and provides a new callback with a stable reference, which will itself always call the latest version of the provided callback. Useful for dealing with third party components that use stale closures. Example: https://tsplay.dev/Bmx07m
import { useRef, useCallback} from 'react';
/**
* Accepts a given callback, and provides a new callback with a stable reference,
* which will itself always call the latest version of the provided callback.
* Useful for dealing with third party components that use stale closures.
* @param callback - the original callback desired to be called
* @returns A new callback with a stable reference, which when called,
* calls the latest provided callback
* @deprecated - This implementation may have future issues in concurrent mode, as it mutates
@Shrugsy
Shrugsy / comparisons.ts
Last active April 3, 2021 07:14
Type Narrowing Identify Function example
type ComparisonFn = (left: number, right: number) => boolean;
// `buildComparison` is a 'Type Narrowing Identity Function'
// It returns the value given to it, but also narrows the types.
// In this case it allows typescript to retain the literal types of the keys
// rather than widening them to 'string'
const buildComparisons = <Comparison extends Record<string, ComparisonFn>>(comparison: Comparison) => comparison;
// Using the Type Narrowing Identity Function:
const comparisons = buildComparisons({
@Shrugsy
Shrugsy / returning-jsx.md
Last active July 31, 2021 14:01
Why is my returned JSX not showing?

Why is my returned JSX not showing?

The problem

You decide you want to show a component on click, so you do this.

function Bar() {
  return <div>This is BAR</div>
}

function Foo() {
@Shrugsy
Shrugsy / ArrayValues.ts
Last active March 31, 2021 14:12
Get a union type derived from values of a const asserted array
/**
* Get a union type derived from values of a const asserted array.
* @example
* const values = ['foo', 'bar'] as const;
* type Val = ArrayValues<typeof values>;
* // => 'foo' | 'bar'
*
* See https://github.com/microsoft/TypeScript/issues/28046#issuecomment-607145719
*/
export type ArrayValues<T extends ReadonlyArray<unknown>> = T[number];
@Shrugsy
Shrugsy / rtkQueryCacheUtils.ts
Last active November 14, 2024 10:31
RTK Query cache utils. Useful abstractions for creating `provides`/`invalidates` cache data tags against endpoints.
import { FetchBaseQueryError } from '@rtk-incubator/rtk-query/dist';
/**
* Default tags used by the cacher helpers
*/
const defaultTags = ["UNAUTHORIZED", "UNKNOWN_ERROR"] as const;
type DefaultTags = typeof defaultTags[number];
function concatErrorCache<T, ID>(
existingCache: CacheList<T, ID>,