Skip to content

Instantly share code, notes, and snippets.

View temoncher's full-sized avatar
🐢

Artem Baranov temoncher

🐢
View GitHub Profile
@temoncher
temoncher / createT.ts
Created May 17, 2024 19:38
small typesafe i18n
import { type O } from 'ts-toolbelt';
type InferInterpolation<TString> =
TString extends `${string}{${infer I}}${infer R}`
? O.Merge<{ [K in I]: string | number }, InferInterpolation<R>>
: object;
type TFunctionParams<
TNamespace,
TKey extends keyof TNamespace,
@temoncher
temoncher / proxied-container.ts
Created April 16, 2024 17:51
Simple di container with object property access to services via proxies
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { type O } from 'ts-toolbelt';
type MapLayer<TServices> =
TServices extends Record<string, (di: any) => any>
? {
[K in keyof TServices]: ReturnType<TServices[K]>;
}
: never;
@temoncher
temoncher / minimal-typed-injector.ts
Last active April 16, 2024 12:05
Minimal typed injector
import { mapValues } from 'remeda';
export class Token<in out T> {
constructor(readonly id: string) {}
}
export declare namespace Token {
export type Type<T extends Token<any>> = T extends Token<infer S> ? S : never;
}
export class Container<in TTokens extends Token<any> = never> {
@temoncher
temoncher / UseHook.tsx
Last active April 13, 2024 12:13
UseHook component
// TODO: make eslint rule only allowing to UseHook inside client components
// TODO: make eslint rule not allowing conditions inside useHook
export function UseHook<T>(props: {
useHook: () => T;
children: (hookResult: T) => JSX.Element;
}) {
const hookResult = props.useHook();
return <>{props.children(hookResult)}</>;
}
@temoncher
temoncher / tinyject.ts
Created April 12, 2024 21:34
IoC containers with almost zero features
class Token<T, Id extends string> {
/** @typeonly */
private readonly __type: T = null!;
constructor(readonly id: Id) {}
}
declare namespace Token {
export type Type<T> = T extends Token<infer TokenType, string> ? TokenType : never;
export type Id<T> = T extends Token<unknown, infer TokenId> ? TokenId : never;
}
@temoncher
temoncher / minimal-angular-style-injector.ts
Created April 6, 2024 12:20
Minimal angular-style injector
let currentInjector: IInjector | null = null;
function runInInjectionContext(injector: IInjector, fn: () => void) {
const prevInjector = currentInjector;
currentInjector = injector;
try {
fn();
} finally {
currentInjector = prevInjector;
@temoncher
temoncher / typed-injector.ts
Last active April 7, 2024 20:40
Typed injector
type NeverIfNotExtends<T, P> = T extends P ? T : never;
type IFactoryBindConfig = {
fresh: true;
eager?: false;
} | {
fresh: false;
eager?: boolean;
}
@temoncher
temoncher / MeshFromPolygonCollider2D.cs
Created February 27, 2024 09:03
Generate mesh and outline for PolygonCollider2D, Unity
using UnityEngine;
[RequireComponent(typeof(PolygonCollider2D))]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(LineRenderer))]
public class MeshFromPolygonCollider2D : MonoBehaviour
{
// Based onh ttp://answers.unity3d.com/questions/835675/how-to-fill-polygon-collider-with-a-solid-color.html
@temoncher
temoncher / jsxt.tsx
Last active January 22, 2024 13:42
jsx tagged template for inline text
/**
* @example
*
* const red = (text) => <span style={{ backgroundColor: 'red', color: 'white', padding: '8px' }}>{text}</span>;
*
* return (
* <>
* {jsxt`Displaying some ${red('red text')} here`}
* </>
* );
@temoncher
temoncher / ZodForm.tsx
Created January 6, 2023 22:08
A more typesafe alternative to `react-hook-form`, useZodForm
import { useState } from 'react';
import { z } from 'zod';
import reactLogo from './assets/react.svg';
import './App.css';
import { useZodForm, register } from './useZodForm';
type ObjectKey = keyof any;
type Field<N extends ObjectKey, V> = {
name: N;