Skip to content

Instantly share code, notes, and snippets.

@pesterhazy
Last active August 12, 2025 11:03
Show Gist options
  • Save pesterhazy/444e51b4b52a06661c8402ff9ee4959c to your computer and use it in GitHub Desktop.
Save pesterhazy/444e51b4b52a06661c8402ff9ee4959c to your computer and use it in GitHub Desktop.
typescript interface unsoundness wat
import test from "node:test";
import assert from "node:assert";
interface IExperiment {
foo(opts: {}): void;
}
class Experiment implements IExperiment {
// Wat?!
// Why is Experiment allowed to implement IExperiment (the typechecker doesn't complain)
// even though IExperiment.foo doesn't guarantee that opts.bar is defined?
foo(opts: { bar: string }): void {
// foo needs opts.bar to be there
assert.ok(opts.bar);
}
}
test.only("experiment", async () => {
const experiment = new Experiment();
experiment.foo({ bar: "baz" });
});
test.only("experiment 2", async () => {
let experiment: IExperiment;
experiment = new Experiment();
experiment.foo({}); // oops, we called foo without passing bar, causing a runtime error
});
/*
How do I change the code so that I can be sure that every class that implements IExperiment
is safe to use with through the interface?
*/
@pesterhazy
Copy link
Author

Thanks to Matt Pollock for pointing me in the right direction https://bsky.app/profile/mattpocock.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment