Skip to content

Instantly share code, notes, and snippets.

@captain-yossarian
captain-yossarian / css-tricks.md
Last active February 1, 2022 20:00
Article for css-tricks

I assume you are familiar with TypeScript mapped types and type inference.

In this article I will try to show you the power of static validation in TypeScript.

Validation of inferred function arguments

Let's start from a small example to better understand the approach. Imagine we have a function which expects some css width value. It may be 100px, 50vh or 10ch. Our function should do anything with argument, because we are not interested in business logic. The naive approach would be to write this:

const units = (value: string) => { }
@captain-yossarian
captain-yossarian / article_dou.md
Last active January 17, 2022 20:33
article_dou

Привіт, мене звати Сергій. Працюю 5 років як Front End програміст, здебільшого з TypeScript. Ця стаття буде присвячена статичній валідації в TypeScript. Я спробую показати коли краще використовувати перезавантаження функції, мапування типів, рекурсії типів чи умовних типів. Усі приклади взяті з практики.

Виведення точних типів

Розглянемо наступний приклад:

class Queue<T> {
private items: T[]
constructor() {
this.items = new Array<T>();
}
enqueue(element: T) {
this.items.push(element);
}
@captain-yossarian
captain-yossarian / algorithms.ts
Last active November 13, 2021 20:29
permutations, bit manipulations
// string permutation
function permut(str: string): string[] | string {
if (str.length === 1) {
return str
}
let result: string[] = [];
for (let i = 0; i < str.length; i++) {
@captain-yossarian
captain-yossarian / useTranslation.ts
Created November 3, 2021 12:47
useTranslation typings
type Dict = typeof dict
type KeysUnion<T, Cache extends string = ''> =
T extends PropertyKey ? Cache : {
[P in keyof T]:
P extends string
? Cache extends ''
? KeysUnion<T[P], `${P}`>
: Cache | KeysUnion<T[P], `${Cache}.${P}`>
: never
type LinkedList<T> = {
value: T,
next: LinkedList<T> | null
}
const cons = (value: number, next: LinkedList<number> | null = null) => {
return { value, next }
}
const lookup = (
const LEAFES = ['left', 'right'] as const;
const hasProperty = <Obj, Prop extends string>(obj: Obj, prop: Prop)
: obj is Obj & Record<Prop, unknown> =>
Object.prototype.hasOwnProperty.call(obj, prop);
const withChildren = <
Type extends Box
>(btree: TreeNode<Type>)
type Elem = Param;
type HandleFalsy<T extends Param> = (
T['x'] extends undefined
? T['y']
: (
unknown extends T['x']
? T['y'] : T['x']
)
)
class Base {
base = 'base'
}
class A extends Base {
a = 'a'
}
class B extends Base {
b = 'b'
}
const fn = <
T extends typeof Base,
Instance extends InstanceType<T>
>(Cls: T & (new () => Instance), prop: keyof Instance,
) => new Cls()[prop];