Skip to content

Instantly share code, notes, and snippets.

@tlux
tlux / FieldsOfType.ts
Last active October 3, 2023 15:27
Extract fields of a specific type from a Record in TypeScript
type AllowedFieldsWithType<TObj, TKey> = {
[K in keyof TObj]: TObj[K] extends TKey ? K : never;
};
export type FieldsOfType<T, K> = AllowedFieldsWithType<T, K>[keyof T];
// Usage Example:
//
// const obj = {
// foo: 'bar',
@tlux
tlux / cloneDeep.ts
Last active October 13, 2023 11:47
Some Typescript utility functions for the real world
/**
* Creates a deep clone of an object.
*
* Internally uses `structuredClone` when available and
* `JSON.parse(JSON.stringify(obj))` as fallback.
*
* @param obj - The object to be cloned.
* @return The deep clone of the object.
*/
export default function cloneDeep<T>(value: T): T {
@tlux
tlux / useScroll.ts
Last active March 24, 2023 03:22
React hook to track and set scroll position of an element
import { RefObject, useCallback, useEffect, useState } from 'react';
export interface ScrollToOptions {
x?: number;
y?: number;
behavior?: ScrollBehavior;
}
export interface UseScrollOptions {
disabled?: boolean;
@tlux
tlux / context.ts
Created March 15, 2023 12:59
Simple TypeScript wrapper to set and get Svelte contexts
import { getContext, setContext } from "svelte";
/**
* The context object.
*/
export interface Context<T> {
get: () => T;
set: (ctx: T) => T;
}
@tlux
tlux / findValue.test.ts
Last active March 2, 2023 09:41
TypeScript helper to find a value in an array, inspired by Elixir's Enum.find_value
import findValue, { FindValueFilterMapper } from './findValue';
describe('findValue(value, predicate)', () => {
const FILTER_MAPPER: FindValueFilterMapper<number, string> = (v) => {
if (v < 0) {
return [true, 'negative'];
}
if (v % 2 === 1) {
return [false, 'odd'];
}
@tlux
tlux / eventually.js
Last active March 1, 2022 14:09
A simple function that resolves when a call eventually does not fail or rejects after a timeout - nice for tests performing async work
export default function eventually(callback, timeout = 2000, pollInterval = 50) {
return new Promise((resolve, reject) => {
let intervalTimer;
let lastError;
const timeoutTimer = setTimeout(() => {
if (!intervalTimer) return;
clearTimeout(intervalTimer);
reject(lastError || new Error('eventually timed out'));
@tlux
tlux / viewport.ts
Last active October 30, 2021 12:19
Svelte Viewport Action
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
let eventType: string;
if (entry.isIntersecting) {
eventType = 'viewportenter';
} else {
eventType = 'viewportleave';
}
@tlux
tlux / Cube.svelte
Last active October 15, 2021 12:59
Cube component with CSS transitions Svelte + TS
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { CubeSide } from './CubeSide';
export let view: CubeSide = CubeSide.Front;
export let transition: boolean = false;
export let transitionDuration: number = 2000;
export let backface: boolean = false;
export let perspective: string = '1000px';
export let width: string = '100%';
@tlux
tlux / formDataToObject.ts
Created January 31, 2021 18:41
FormData to object (Typescript)
export function formDataToObject(formData: FormData): Record<string, FormDataEntryValue> {
const data: Record<string, FormDataEntryValue> = {};
for (let [key, value] of formData.entries()) {
data[key] = value;
}
return data;
}
@tlux
tlux / install_vips.sh
Last active June 20, 2020 11:13
Download, build and install a specific version of libvips from source (Ubuntu)
#/bin/bash
set -ex
VERSION="8.8.4"
# or: VERSION="$1"
if [ "$VERSION" = "" ]
then
echo "no version specified" >&2