Skip to content

Instantly share code, notes, and snippets.

@JSuder-xx
JSuder-xx / fluent_mapper_builder_gist.ts
Created January 12, 2019 17:59
Explicitly declare modifications to an existing object type via a fluent interface which yields a mapping function to the derived type. Demonstration of TypeScript meta-programming through mapped and conditional types.
/**
* _Explicitly declare modifications_ to an existing object type via a fluent interface which yields a mapping function
* from the original data type to the type derived from the modification commands.
*
* The value over authoring a simple mapping function directly
* * harder to make a mistake due to the explicit nature
* * easier to read.
*
* This is _not_ production quality code but rather a _proof of concept_ gist for applying conditional/mapped
* types to mapper generation. A real-world usage might involve also generating the type-guard function
@JSuder-xx
JSuder-xx / expressions_refining_environment.ts
Last active January 7, 2020 02:43
An application of TypeScript conditional/mapped/literal types to Expression construction which yields an inferred static type for the Environment that would satisfy the needs of the Expression. This is magic.
/**
* When implementing the evaluation of a tree of expressions, an environment/context/memory representation is typically passed as an
* argument (or injected into the constructor of the interpreter class for OO realizations of the pattern) in order to give the
* expressions access to a memory store.
*
* The *Type* of the memory does not normally relate to any specific constructed expression ex. the memory may be implemented as an
* _arbitrary_ dictionary of key/value pairs. As such, there is no way to know if a type or instance of a dictionary of values can
* satisfy the needs to a specific constructed expression.
*
* For example, the following expression reads a number named 'x' from the environment and therefore the expression _requires_ an x of type number
@JSuder-xx
JSuder-xx / karatsuba_multiplication.ts
Created March 18, 2019 16:55
Karatsuba multiplication implemented in TypeScript with in-baked unit tests (from Standford Algorithms course).
module Logging {
let indent = 0;
let enabled = false;
const indentedMessage = (msg: string) =>
Array(indent * 2).fill("").join(" ") + msg;
export const log = (msg: string) => {
if (enabled)
console.log(indentedMessage(msg));
@JSuder-xx
JSuder-xx / constrained_fluent_builder.ts
Last active May 4, 2022 02:54
Fluent Builder Type API which transforms any arbitrary fluent builder type into a fluent builder type enforcing call count dependencies between methods (where dependencies are represented as a type). Employs Mapped, Conditional, and Literal Types to demonstrate both TypeScript's proximity to dependent typing and the practical value.
/**
* Imagine a Fluent Builder where some subset of the fluent methods are valid to call
* * after one or more fluent methods have been called
* * before one or more fluent methods have been called
* * limited number of times.
*
* There is no way to enforce such constraints in statically typed languages such as C++, C# or Java when using a single builder
* class/interface. Developers would need to author many interfaces to represent the different shapes and would likely need to
* author many versions of the builder itself (proxies with a specific signature delegating to an underlying source builder).
*
@JSuder-xx
JSuder-xx / can_js_view_model_type_inference.ts
Created February 18, 2020 00:59
Inferring a strong static type signature from the CanJS dynamic view model API.
/**
* Demonstrate inferring a strong type signature from the CanJS dynamic view model API.
*/
module ReadMe {}
module ViewModelTypes {
/** Definition of a "class". */
export type Definition = { attributes: any }
}
@JSuder-xx
JSuder-xx / micro_type_predicate.ts
Last active February 7, 2021 16:09
Micro Api for building type predicates in TypeScript.
/** Micro Api for building type predicates */
module TypePredicateApi {
export type TypePredicate<refined> = (val: any) => val is refined;
export type TypeOfTypePredicate<refiner> = refiner extends TypePredicate<infer refined> ? refined : never;
export type TypePredicateMap = { [propertyName: string]: TypePredicate<any> }
export type ObjectFromTypePredicateMap<map extends { [propertyName: string]: TypePredicate<any> }> = {
[propertyName in keyof map]: TypeOfTypePredicate<map[propertyName]>;
}
/** Create a predicate which tests for an object. */
@JSuder-xx
JSuder-xx / typescript_peano_and_list.ts
Created February 7, 2021 16:35
Peano numbers and linked lists verified in the type system (dependent typing) in TypeScript.
/**
* **Power of Infer**
* Infer allows us to match a type for a structure and unpack the internal structure of that type
* into local type variables. This is essentially destructuring/deconstructing/elimination.
*
* The are two fundamental computation operations
* * Building up or constructing types - which can be done with Mapped Types (comprehension).
* * Unpacking types - which can be done with the combination of Conditional Types and the use of infer.
*
* The examples below are the poster-child for this idea of computation through construction/deconstruction
@JSuder-xx
JSuder-xx / micro_decoder.ts
Created February 8, 2021 17:06
A micro JSON decoder API in TypeScript.
/** Micro Api for building decoders. */
module DecoderApi {
type Unknown = unknown;
type ErrorMessage = { kind: "error"; error: string }
export const errorMessage = (error: string): ErrorMessage => ({ kind: "error", error });
export type DecodeResult<value> = value | ErrorMessage
export const isErrorMessage = <value extends unknown>(result: DecodeResult<value>): result is ErrorMessage =>
!!result &&
typeof result === "object" &&
(result as any).kind === "error";
@JSuder-xx
JSuder-xx / safe_apis.ts
Last active February 11, 2021 01:04
Example of building safe APIs with type driven development in TypeScript.
/**
* Yet another demonstration of TypeScript awesomeness
* - NonEmptyString demonstrates a simple tagged type (similar to single-case-union in FP).
* - DBConfiguration shows off both union and boolean literal types.
* - EnvironmentDBConfigurationMap finishes with a smart fluent builder utilizing Conditional and Mapped types
* along with type intersection to create a Fluent Builder with stronger verification than is possible
* in C#/Java/C++.
*
* See the TRY comments for things to... well... try.
*
@JSuder-xx
JSuder-xx / safe_strings.ts
Created February 11, 2021 00:51
An example of type system verified strings in TypeScript using template literal strings and tagged types.
/**
* Yet another demonstration of TypeScript awesomeness.
*
* Demonstrates tagged types and template literal strings (v4.1) which allows
* * for the type system to infer the literal string type of value
* * then deconstruct the literal string type into parts
* * in order to parse and validate strings directly in the type system.
*
* See the TRY comments for things to try.
*