Skip to content

Instantly share code, notes, and snippets.

dsherret / getDeepMutableClone.ts
Last active Dec 11, 2019
Cloning a TypeScript compiler API node.
View getDeepMutableClone.ts
// one way...
function getDeepMutableClone<T extends ts.Node>(node: T): T {
return ts.transform(node, [
context => node => deepCloneWithContext(node, context)
function deepCloneWithContext<T extends ts.Node>(
node: T,
context: ts.TransformationContext
dsherret / proxiedClone.ts
Last active Nov 23, 2019
Cloning an immutable object via a proxy.
View proxiedClone.ts
// I wrote this to test if it would be faster for my scenario and it wasn't... it was much much slower.
// So I'm throwing it away here on a gist. Perhaps someone would still find it useful.
* Mimicks the behaviour of cloning via a proxy for when the underlying object
* will never change, but the clone might.
* @param originalObject - Object to create a proxied clone of.
export function proxiedClone<T extends object>(originalObject: T): T {
const proxies = new Map<object, object>();
View MelFrequencyBinner.cs
// Adapted from:
using System;
using System.Diagnostics;
namespace CommonShared.Audio
public class MelFrequencyBinner
private const int _melFiltersCount = Constants.MEL_FILTERS_COUNT;
dsherret / transform-to-relative-module-specifiers.ts
Last active Jan 12, 2019
Converts all module specifiers within a directory to relative paths.
View transform-to-relative-module-specifiers.ts
// untested...
import { Project, SyntaxKind } from "ts-simple-ast";
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
const srcDir = project.getDirectoryOrThrow("./src");
for (const sourceFile of project.getSourceFiles().filter(s => srcDir.isAncestorOf(s))) {
for (const dec of [...sourceFile.getImportDeclarations(), ...sourceFile.getExportDeclarations()]) {
const moduleSpecifierSourceFile = dec.getModuleSpecifierSourceFile();
if (moduleSpecifierSourceFile == null || !srcDir.isAncestorOf(moduleSpecifierSourceFile))
dsherret / prefix-internal-class-members.ts
Last active Jan 12, 2019
Programmatic refactor to prefix all private, protected, and internal class members with an underscore.
View prefix-internal-class-members.ts
// This script will look at all the exported class declarations from the main entrypoint of a library
// and ensure all private, protected, and @internal members are prefixed with an underscore.
import { Project, Node, SyntaxKind, TypeGuards, Scope, ClassMemberTypes, ParameterDeclaration } from "ts-simple-ast";
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
const sourceFiles = project.getSourceFiles();
for (const file of sourceFiles)
for (const classDec of file.getDescendantsOfKind(SyntaxKind.ClassDeclaration))
for (const member of classDec.getMembers())
dsherret / find-unused-exports.ts
Last active Apr 21, 2022
Searches files for any exported declarations that aren't used in other files.
View find-unused-exports.ts
// this could be improved... (ex. ignore interfaces/type aliases that describe a parameter type in the same file)
import { Project, TypeGuards, Node } from "ts-morph";
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
for (const file of project.getSourceFiles()) {
file.forEachChild(child => {
if (TypeGuards.isVariableStatement(child)) {
if (isExported(child))
dsherret / ensure-public-api-has-tests.ts
Last active Sep 24, 2018
Analyzes code to find missing tests.
View ensure-public-api-has-tests.ts
* Ensure Public API Has Tests
* ---------------------------
* This demonstrates analyzing code to find methods and properties from the public
* api that don't appear in the tests.
* This is a very basic implementation... a better implementation would examine more
* aspects of the code (ex. are the return values properly checked?) and report
* statistics about the tests that possibly indicate how they could be improved (ex.
* "this test has a lot of overlap with these other tests"). The goal would be to
View tsquery-with-ts-morph.ts
import { tsquery } from "@phenomnomnominal/tsquery";
import { Node } from "ts-morph";
export function query(node: Node, query: string) {
return tsquery(node.compilerNode, query)
.map(n => (node as any)._getNodeFromCompilerNode(n) as Node);
dsherret / WeakCache.ts
Last active Sep 27, 2018
A weak cache with support for ES5.
View WeakCache.ts
export class WeakCache<T extends object, U> {
private readonly cacheItems: WeakDictionary<T, U>;
constructor() {
if (typeof WeakMap !== "undefined")
this.cacheItems = new WeakMap<T, U>();
this.cacheItems = new Es5WeakMap();
View EnumEx.ts
// only works with number enums...
class EnumEx {
private constructor() {
static getMembersCount(e: any) {
return EnumEx.getNames(e).length;
static getMemberValue(e: any, memberName: string) {