Skip to content

Instantly share code, notes, and snippets.

@dsherret
dsherret / avoid_prs_main_branch.md
Last active November 20, 2025 15:58
Avoid opening PRs from your `main` branch

I highly recommend not opening PRs from the main branch of your fork.

Why?

  1. Maintainers usually can't push fixes to your main branch. GitHub often blocks maintainers from making changes directly to a contributor's main branch.
    • I regularly need to make small edits (sometimes just one line) to get a PR ready to merge.
    • This mostly works fine if the PR comes from a non-main branch, but not from main.
  2. It complicates keeping your fork in sync. After your PR is merged, your fork's main branch ends up diverging from the upstream main.
@dsherret
dsherret / generate.js
Last active February 17, 2025 04:01
@types packages on npm with dependencies outside the @types scope
// How to generate output:
// > git clone https://github.com/DefinitelyTyped/DefinitelyTyped
// > cd DefinitelyTyped
// > deno run --allow-read <url-to-this-file-goes-here> (click raw in the top right corner for url)
import { Path } from "jsr:@david/path@0.2";
const typesDir = new Path("./types");
const entries = typesDir.readDirSync();
for (const entry of entries) {
if (!entry.isDirectory) {
@dsherret
dsherret / getDeepMutableClone.ts
Last active December 11, 2019 21:13
Cloning a TypeScript compiler API node.
// one way...
function getDeepMutableClone<T extends ts.Node>(node: T): T {
return ts.transform(node, [
context => node => deepCloneWithContext(node, context)
]).transformed[0];
function deepCloneWithContext<T extends ts.Node>(
node: T,
context: ts.TransformationContext
@dsherret
dsherret / proxiedClone.ts
Last active November 23, 2019 05:03
Cloning an immutable object via a proxy.
// 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>();
// Adapted from: https://github.com/Sciss/SpeechRecognitionHMM/blob/master/src/main/java/org/ioe/tprsa/audio/feature/MFCC.java
using System;
using System.Diagnostics;
namespace CommonShared.Audio
{
public class MelFrequencyBinner
{
private const int _melFiltersCount = Constants.MEL_FILTERS_COUNT;
@dsherret
dsherret / transform-to-relative-module-specifiers.ts
Last active January 12, 2019 00:54
Converts all module specifiers within a directory to relative paths.
// 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
dsherret / prefix-internal-class-members.ts
Last active January 12, 2019 00:54
Programmatic refactor to prefix all private, protected, and internal class members with an underscore.
// 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
dsherret / find-unused-exports.ts
Last active December 22, 2023 00:03
Searches files for any exported declarations that aren't used in other files.
// 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))
child.getDeclarations().forEach(checkNode);
@dsherret
dsherret / ensure-public-api-has-tests.ts
Last active September 24, 2018 18:02
Analyzes code to find missing tests.
/**
* 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
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);
}