Skip to content

Instantly share code, notes, and snippets.

Avatar
🤪
All you need is Half-Life 3

Fosty Fost fostyfost

🤪
All you need is Half-Life 3
View GitHub Profile
View counter.test.ts
import type { CountedItem} from './counter';
import { getCounter } from './counter'
describe('Counter tests', () => {
it('should work with functions', () => {
const noop1 = () => null
const noop2 = () => null
const counter = getCounter()
View known-keys.ts
type KnownKeys<T> = {
[K in keyof T]: string extends K ? never : number extends K ? never : K
} extends { [_ in keyof T]: infer U } ? U : never;
View redux-saga-call-effect-return-type.d.ts
import type { SagaIterator } from 'redux-saga'
declare type YieldReturnType<T> = ReturnType<T> extends Promise<infer U>
? U
: ReturnType<T> extends SagaIterator<infer U>
? U
: ReturnType<T>
@fostyfost
fostyfost / action-creator.ts
Last active Jul 8, 2021
Redux Action Helper
View action-creator.ts
import type { ActionsUnion } from '@/store/action-helper'
import { createAction } from '@/store/action-helper'
export enum StoreActionType {
HYDRATE = '@@store/HYDRATE',
}
export const StoreAction = {
hydrate(payload: Record<string, unknown>) {
return createAction(StoreActionType.HYDRATE, payload)
View extract-return-types.d.ts
type ExtractReturnTypes<T extends ((...args: unknown[]) => unknown)[]> = [
...{ [K in keyof T]: T[K] extends ((...args: unknown[]) => infer R) ? R : never }
]
@fostyfost
fostyfost / saga-equals.ts
Created Jul 6, 2021
Saga equals function
View saga-equals.ts
export interface SagaWithArguments<T = any> {
saga: (argument?: T) => Iterator<any>
argument?: T
}
export type SagaRegistration<T = any> = (() => Iterator<any>) | SagaWithArguments<T>
export const sagaEquals = (sagaA: SagaRegistration, sagaB: SagaRegistration): boolean => {
if (typeof sagaA === 'function' && typeof sagaB === 'function') {
return sagaA === sagaB
View comparable-map.ts
export interface ComparableMap<K = string, V = unknown> {
keys: K[]
get(key: K): V | undefined
add(key: K, value: V): void
remove(key: K): V | undefined
}
/**
* We will use it where we can not use the default Map as the Map class do not allow custom compare function.
*
View get-string-ref-counter.ts
export interface RefCounter<T = unknown> {
getCount(item: T): number
add(item: T): void
remove(item: T): void
}
export const getStringRefCounter = (): RefCounter<string> => {
const values: Record<string, number | undefined> = {}
const getCount = (key: string): number => values[key] || 0
View array.flatten.ts
type TupleRecursive<T> = T | Tuple<T>
export type Tuple<T> = TupleRecursive<T>[]
export const flatten = <T>(tuple: Tuple<T>): T[] => {
const result: T[] = []
const flat = (tuple: Tuple<T>): void => {
tuple.forEach(item => {
if (Array.isArray(item)) {
@fostyfost
fostyfost / unflat.js
Created Dec 8, 2020 — forked from szanata/unflat.js
Unflat js object
View unflat.js
function isObject(item) {
return (item && typeof item === 'object' && !Array.isArray(item));
}
function mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {