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
/** Stricter keyof */ | |
export type RecordKey<T> = T extends Partial<infer R> ? (R extends Record<infer K, unknown> ? K : never) : never; | |
/** Stricter type for members of Object.entries(t) */ | |
export type RecordEntry<T> = { [K in RecordKey<T>]: [K, Required<T>[K]] }[RecordKey<T>]; | |
/** Type-narrowed equivalent of Object.entries */ | |
export function entries<T extends Readonly<NonNullable<{}>>>(obj: T) { | |
return Object.entries(obj) as RecordEntry<T>[]; | |
} |
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
/** The union of the types of members of array `Arr` */ | |
export type MemberOf<Arr extends readonly unknown[]> = Arr[number]; | |
// from https://stackoverflow.com/a/65914848/2257198 | |
type Tuple<T, N extends number, A extends unknown[] = []> = A extends { length: N } ? A : Tuple<T, N, [...A, T]>; | |
export function composeTuple<Item, Length extends number, LengthCast = [...Item[]]>(item: Item, length: Length) { | |
return Array.from({ length }).map(() => item) as LengthCast; | |
} |
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
export function decorateSequence< | |
G extends Generator<Yielded>, | |
Yielded, | |
Decorated | |
>( | |
generator: G, | |
decorate: (yielded: Yielded) => Decorated | |
): Generator<Decorated, GReturned<G>, GNexted<G>> { | |
function mapResult( | |
result: IteratorResult<Yielded, GReturned<G>> |
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
type Passage = string; | |
async function tell(passage: Passage): Promise<void> {} | |
async function choose<Choice extends string>( | |
passage: Passage, | |
choices: Record<Choice, Passage> | |
): Promise<Choice> { | |
return Object.keys(choices)[0] as Choice; | |
} |
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
export type Returned< | |
G extends Generator<any, any, any> | AsyncGenerator<any, any, any> | |
> = G extends Generator<any, infer TReturn, any> | |
? TReturn | |
: G extends AsyncGenerator<any, infer AsycTReturn, any> | |
? AsycTReturn | |
: never; |
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
export type Yielded< | |
G extends Generator<any, any, any> | AsyncGenerator<any, any, any> | |
> = G extends Generator<infer T, any, any> | |
? T | |
: G extends AsyncGenerator<infer AsyncT, any, any> | |
? AsyncT | |
: never; |
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
type IndexOf<T extends {length: number}> = Exclude<Partial<T>["length"], T['length']> & number; |
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
function waitableJestFn<Result, Args extends any[]>( | |
implementation?: (...args: Args) => Result, | |
) { | |
const mock = jest.fn<Result, Args>(implementation); | |
const asyncMethods = { | |
waitForCallback: (count = 1) => | |
new Promise<Args>((resolve) => { | |
mock.mockImplementation(((...args) => { | |
count--; | |
if (count === 0) resolve(args); |
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
import { computed, ComputedRef } from 'vue'; | |
export function followDescendantsByName< | |
ReactiveParent, | |
ChildKeys extends ReadonlyArray<keyof ReactiveParent>, | |
>(parentSelector: () => ReactiveParent, childKeys: ChildKeys) { | |
return Object.fromEntries( | |
childKeys.map((childKey) => { | |
return [childKey, computed(() => parentSelector()[childKey])]; | |
}), |
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
import * as dotenv from 'dotenv'; | |
dotenv.config(); | |
const VARS = { | |
API_TOKEN: 'an API token', | |
API_URL: 'a URL for an endpoint', | |
} as const; | |
for (const [varname, description] of Object.entries(VARS)) { |
NewerOlder