Skip to content

Instantly share code, notes, and snippets.

castarco / TypedRegistryPattern.ts
Last active February 9, 2022 13:13
A "new" pattern to create fully-typed registries/containers!
// This first file contains the first iteration of this pattern. It's already
// nice, but not enough for full-fledged IoC libraries.
// There's a second file in this same gist that goes one step further, although,
// for now, it still needs some extra polish.
// -----------------------------------------------------------------------------
// First: the two main interfaces.
// They are the core of the pattern.
// -----------------------------------------------------------------------------
export interface WritableRegistry {
// We use symbols to eliminate any chance for problems with serialization
const __BaseType: unique symbol = new Symbol('__BaseType')
const __Brand: unique symbol = new Symbol('__Brand')
// We mark the "brand/flavor" fields as readonly to avoid anyone doing weird stuff with them
// We add a "__BaseType" field to make possible "complex" type manipulations
// We accept "symbol" tags as a mechanism to avoid "types forgery" to bypass the type checker,
// although I foresee that most of the times it won't be used.
export type Branded<BaseType, Tag extends string | symbol> = BaseType & {
readonly [__BaseType]: BaseType
castarco / composableNominalTypes.ts
Last active March 11, 2021 12:59
Composable Nominal Types for Typescript
export type ChainNominal<BaseType, Tag extends string> = BaseType extends {
__type: infer Tag0
__baseType: infer BaseType0
? Tag0 extends [...infer NestedTags]
? BaseType0 & { __type: [Tag, ...NestedTags]; __baseType: BaseType0 }
: never
: BaseType & {
__type: [Tag] // Using an array allow us to use multiple type tags :3
__baseType: BaseType // Only here to ease type inference
* This approach has many limitations:
* - it does not accept variable names with numbers or other symbols (relatively easy to fix)
* - it does not accept arbitrary expressions (quite difficult to fix)
function deferredTemplateLiteral(template: string, env: { [key: string]: string | undefined }): string {
const varsMatcher = /\${([a-zA-Z_]+)}/
const globalVarsmatcher = /\${[a-zA-Z_]+}/g
const varMatches: string[] = template.match(globalVarsmatcher) ?? []
castarco /
Created August 27, 2019 15:55

Keybase proof

I hereby claim:

  • I am castarco on github.
  • I am castarco ( on keybase.
  • I have a public key whose fingerprint is 9D10 B5B4 1B15 934F C867 8397 40BB CA62 EF4B 86CC

To claim this, I am signing this object:

castarco / array_zip.php
Last active June 10, 2018 20:06
PHP's array_zip
function array_zip(array ...$arrays): array
// Applied suggestion from reddit
return \array_map(null, ...$arrays);
castarco / ds_vector_benchmark.php
Created December 16, 2016 14:37
Simple benchmark for RW operations on Ds\Vector (PHP)
* Requires the DS extension (see
* This script is a benchmark for simple RW operations on Ds\Vector (without affecting its length)
* RESULTS (the times are not divided by the number of iterations, only numbers in the same row can be compared):
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
castarco / matrix_benchmark.php
Last active December 15, 2016 18:29
PHP Matrix multiplication benchmark
* Requires the DS extension (see
* This script is a benchmark for many possible combinations to perform matrix multiplications:
* - Ds\Vector vs PHP array
* - Single array vs Nested arrays
* - iterations order: I,J,K vs I,K,J