Skip to content

Instantly share code, notes, and snippets.

@kaleidawave
Last active September 24, 2025 11:46
Show Gist options
  • Select an option

  • Save kaleidawave/81066f322ed574b3373e27770137013f to your computer and use it in GitHub Desktop.

Select an option

Save kaleidawave/81066f322ed574b3373e27770137013f to your computer and use it in GitHub Desktop.
as of 21/09/25 (temp)
() => {
const x: number = 2
const y: string = 2
const z: object = 4
const a = 3
const b: string = a
const exists = 2;
nexists
doesNotExist = 4;
let first = second;
let second = 2;
{
// Fine
var x = 2;
x satisfies 2;
var x = 3;
x satisfies 3;
}
{
let b = 2;
var b = 2;
}
const my_obj = { a: 2 }
const three: 3 = my_obj.a
let global: number = 0;
const object = {
// This getter has an impure side effect
get value() {
return ++global
},
}
object.value satisfies string
object.value satisfies boolean
const obj = {
set value(v: string) { }
}
obj.value = 5;
const result = ({ set value(a) { return { a: 3 } }}).value = 5;
result satisfies string;
const obj1 = { a: 2, b: 3 };
const obj2 = { b: 4, ...obj1, a: 6 };
obj2.b satisfies 100;
obj2.a satisfies boolean;
declare type U = { a: 2 } & { b: 3 };
void function declare_variables(x: U) {
x.b satisfies 3;
({ a: 2, b: 3 } satisfies U);
({ b: 3 } satisfies U)
}
function func(idx: number) {
const array = [1, 2, 3];
array[idx] satisfies string;
}
void function declare_variables(strings: { [a:string]: number }, record: Record<string, number>, d: { [a:"a" | "b"]: number }) {
strings.a satisfies number | undefined;
record.a satisfies boolean;
d.a satisfies number
}
{
const obj = {}
Object.isExtensible(obj) satisfies true;
Object.preventExtensions(obj);
Object.isExtensible(obj) satisfies false;
}
{
const obj = {}
Object.seal(obj);
Object.isExtensible(obj) satisfies false;
}
{
const obj = {}
Object.freeze(obj);
Object.isExtensible(obj) satisfies 5;
}
interface MyObject { property: string }
function returnNewObject(): MyObject {
return { property: "hello", another: 67 }
}
(4 === 2) satisfies true;
(4 !== 5) satisfies string;
(Math.PI > 3) satisfies true;
(4 < 2) satisfies true;
(4 > 2) satisfies number;
(6 >= 2) satisfies string;
(6 <= 2) satisfies 5;
"hi".toUpperCase() satisfies number
Math.cos(0) satisfies 0
Math.sqrt(16) satisfies 1
Math.floor(723.22) satisfies 2;
("something"[2]) satisfies number;
function outer(a: number) {
function inner(b: string = Math.floor(a)) {
}
}
function getSecond1<T, U>(p1: T, p2: U): U {
return p1
}
function getSecond2<T, U>(p1: T, p2: U): U {
return p2
}
function setFirst1<T, U>(a: T, b: U) {
const a2: T = a;
}
function setFirst2<T, U>(a: T, b: U) {
const a2: U = a;
}
function createObject1<T, U>(a: T, b: U): { a: T, b: U } {
return { a, b }
}
function createObject2<T, U>(a: T, b: U): { a: U, b: U } {
return { a, b }
}
function map(a: (a: number) => number) {}
// No annotation on `a`. But error comes from body
// (rather than parameter assignment)
map(a => a.t);
function alterParameter(a: number, b: { prop: string }) {
a = 2;
a = "hi";
b.prop = 3;
b.prop = "hello";
// Observed. TODO disabled because of possible impure (getters etc)
// b.prop satisfies "hello";
}
function variadic(...r: string[]) {
r satisfies boolean;
}
function myFunction({ a }: { a: number }) {
a satisfies boolean;
return a
}
myFunction({ a: 6 }) satisfies string;
function getNumber1(): number {
return 4
}
function getNumber2() {
return 6
}
getNumber1 satisfies () => 4;
getNumber2 satisfies () => 6;
getNumber1() satisfies 4;
getNumber2() satisfies 6;
function id(a: number) {
return a
}
function simple() {
return "hello world"
}
id satisfies (n: number) => number;
simple satisfies () => number;
function throwSomething() {
throw "to implement!"
}
throwSomething satisfies string;
function getA(obj: { a: string }) {
return obj.a
}
const d: 3 = getA({ a: "hi" });
function addTwoToResult(func: (n: number) => number) {
return func(4) + 2
}
addTwoToResult((a: number) => a * 4) satisfies 5
function call(func: (n: number) => number) {
return func(9)
}
call(Math.sqrt) satisfies 2
function floorPlusB(a: number, b: number) {
return Math.floor(a) + b
}
floorPlusB(100.22, 5) satisfies 8
function getToUpperCase(s: string) {
return s.toUpperCase
}
getToUpperCase("hi")() satisfies "HEY";
function callToUpperCase(s: string) {
return s.toUpperCase()
}
callToUpperCase("hi") satisfies "HEY";
const { toUpperCase } = "hi";
toUpperCase();
function MyClass(value) {
this.value = value
}
new MyClass("hi").value satisfies "hello"
function myRestFunction(...r: string[]) {
return r
}
myRestFunction("hello ", "world") satisfies number;
function withDefault(x: number = 1) {
return x
}
withDefault() satisfies 2;
withDefault(3) satisfies 3;
function optionally(p?: number) {
p satisfies string;
}
function doThing(a: number, b: number = (a += 2)) {
return a
}
doThing(3) satisfies 2;
doThing(6, 1) satisfies 6;
function myTag(static_parts: Array<string>, count: number) {
}
myTag`Count is ${"not a number!!"}`;
function createNew(cb: { f<T>(t: T): { a: T }}["f"]) {
return cb(4)
}
createNew satisfies string;
class StringBuilder {
s: string = ""
append(s: string) {
this.s += s;
return this
}
finish() {
return this.s
}
}
(new StringBuilder).append("Hello ").append("Ben").finish() satisfies number
function isFive(a: number): boolean {
return a === 5
}
isFive(5) satisfies true;
isFive(6) satisfies string;
function hasPropertyX(obj: object): boolean {
return "x" in obj;
}
hasPropertyX({ a: 2 }) satisfies false;
hasPropertyX({ x: 5 }) satisfies number;
let myObject: { a: number } = { a: 4 }
function readA(someObject: { a: number | string }) {
return someObject.a;
}
function setAtoString(someObject: { a: number | string }) {
someObject.a = "hi";
}
// Allowed
readA(myObject);
setAtoString({ a: 6 });
setAtoString(myObject);
function getObject(condition: boolean) {
const mainObject = { a: 2 };
const object = condition ? mainObject : { b: 3 };
object.c = 4;
mainObject.c satisfies string;
return mainObject
}
function throwGreeting() {
throw "Hello";
return "Unreachable!"
}
function doSomething() {
throwGreeting()
const unreachable = 2;
}
let i: number = 0;
({ a: true})?.[i++, "a"] satisfies true;
i satisfies 1;
null?.[i++, "a"];
i satisfies string;
function kestrel(a) {
return function (_b) {
return a
}
}
kestrel(3)(2) satisfies 4
function kestrel2(a) {
return b => c => (a * b) + c
}
kestrel2(3)(2)(1) satisfies 4
function magicNumber(a: number) {
return {
plusOne() { return a + 1 },
doubled() { return 2 * a }
}
}
const myNumber = magicNumber(4);
// Create a one in between to test they don't have a global state
magicNumber(8).doubled() satisfies 16;
myNumber.plusOne() satisfies 5
myNumber.doubled() satisfies 6
function myClosure(a) {
return {
getValue() { return a },
setValue(b) { a = b }
}
}
const value = myClosure(4);
value.getValue() satisfies 4;
value.setValue(10);
value.getValue() satisfies 6
function isNegative(x: number) {
return x < 0 ? "negative" : "positive"
}
isNegative(-4) satisfies number
isNegative(4) satisfies boolean
function print_number(value: number) {
if (value === 0) {
return "zero"
} else if (value === 1) {
return "one"
} else {
return "some number"
}
}
print_number(0) satisfies "zero"
print_number(0) satisfies "some number"
print_number(1) satisfies "ONE"
print_number(100) satisfies "100"
print_number(-1) satisfies "TWO"
void function declare_variables(string: string) {
function stringIsHi(s: string) {
if (s === "hi") {
return true
}
return false
}
stringIsHi(string) satisfies number
}
function loop(n: number, c: string) {
let a: string = c;
let i: number = 1;
while (i++ < n) {
a += c
}
return a
}
loop(10, "!") satisfies number;
let properties: string = "";
for (const property in { a: 1, b: 2, c: 3 }) {
properties += property;
}
properties satisfies boolean;
try {
throw 2
} catch (err) {
err satisfies string
}
console.log("Error caught!");
function exceptionToResult(cb: () => number) {
try {
return cb()
} catch (e) {
return e
}
}
exceptionToResult(() => 6) satisfies 6;
exceptionToResult(() => { throw 12 }) satisfies 8;
console.log("Error caught!");
// no complex numbers :(
function checkedLn(x: number) {
if (x > 0) {
return Math.log(x)
} else {
throw new Error("Cannot log")
}
}
// Fine
try { checkedLn(Math.E ** 3) satisfies 3 } catch {}
// Will throw
try { checkedLn(-5) } catch {}
const myArray = [6, "hi"]
myArray.pop() satisfies 3;
myArray.length satisfies 1;
function fakeRead(a: Array<string | number>) {
a.push(2)
}
const array1: Array<string> = []
fakeRead(array1);
console + 2
function isLessThan(a: number) {
a < console;
}
function neverEqual(a: string, b: number) {
(a === b) satisfies false;
}
function sometimes(a: string | number, b: number) {
(a === b) satisfies string;
}
void function declare_variables(getNumberBetweenFive: () => InclusiveRange<0, 5> & Integer) {
getNumberBetweenFive() === 2;
getNumberBetweenFive() === 2.2;
getNumberBetweenFive() === 7
}
function func1(param: Not<string>) {
return "hi" === param;
}
function func2(param: Not<string>) {
return 4 === param;
}
function func3(p1: Not<string>, p2: Not<number>) {
return p1 === p2;
}
type MyNumber = number;
type MyObj = { a: string };
void function declare_variables(obj: MyObj) {
"hi" satisfies MyNumber;
4 satisfies MyNumber;
obj.a satisfies string
}
void function declare_variables(global_number: number) {
const my_number: string = global_number
}
undefined satisfies null;
null satisfies undefined;
(void 2) satisfies string;
const name = "Ben";
`Hello ${name}` satisfies "Hi Ben"
void function declare_variables(x: number) {
(x * 2) satisfies string
}
void function declare_variables(x: number) {
(x < 4) satisfies string;
(x === 4) satisfies Math;
(x !== 4) satisfies boolean;
(x > 4) satisfies boolean;
(x >= 4) satisfies boolean
}
void function declare_variables(x: number, y: boolean) {
(x && y) satisfies string
}
interface X {
a: string,
b: boolean
}
{
interface X {
c: number
}
const x: X = { a: "field", b: false, c: false }
const y: X = { a: "field", b: false, c: 2 }
}
void function declare_variables(global: any) {
5 as boolean;
global satisfies boolean;
(global as string) satisfies number
}
void function declare_variables(global: { property: string }) {
global.property satisfies string | undefined;
global.property! satisfies number
}
s satisfies string;
var s = "hello"
s satisfies number;
interface BoxString<T extends string> {
inner: T
}
type BoxedFour = BoxString<"4">;
type BoxedFive = BoxString<5>;
const regexp = /hi/ satisfies string;
const regexp1 = /(?a2)/;
const regexp2 = new RegExp("?a2");
const resp = await (fetch("/some-endpoint") satisfies string);
resp.ok satisfies number;
class BaseClass {
b: boolean = false
}
class Class extends BaseClass {
a: number = 2
}
new Class().b satisfies 5
class Box<T> {
value: T;
constructor(value: T) {
this.value = value;
}
}
const myBox = new Box<number>("hi");
function getProp(obj: { prop: 3, prop2: 6 } | { prop: 2 }) {
obj.prop2;
return obj.prop
}
getProp satisfies string
function runWithCallback(cb: () => void): void {
cb() satisfies string;
return 5;
}
runWithCallback(() => 3);
interface ThePrimitives {
a: number,
b: string,
c: boolean
}
2 satisfies ThePrimitives["b"];
function getFirst(array: number[]) {
return array[0]
}
getFirst satisfies boolean;
function getSecondCharacter(s: string) {
return s[1]
}
getSecondCharacter satisfies boolean;
getSecondCharacter("string") satisfies "b";
function or1<T, U>(obj: T | U): U | T { return obj }
function or2(obj: string | number): number | string { return obj }
// Lack of symmetry
function or3(obj: string | number): number { return obj }
function and1<T, U>(obj: T & U): U & T { return obj }
// Lack of symmetry
function and2<T, U>(obj: T): U & T { return obj }
function distribute1<T, U, V>(obj: (T | U) & V): (T & V) | (U & V) { return obj }
function distribute2<T, U, V>(obj: V & (T | U)): (T & V) | (U & V) { return obj }
// bad!
function distribute3<T, U, V>(obj: (T | U) & V): (T & U) | (U & V) { return obj }
function get(obj: {a: 2} | { b: 3 }) {
return obj.a
}
interface Optional {
a?: "hi"
}
const op1: Optional = {}
const op2: Optional = { a: "hello" }
type Node<T> = { parent: Node<T>, value: T } | null;
null satisfies Node<number>;
({ parent: { parent: { parent: null, value: 2 }, value: 6 }, value: 2 } satisfies Node<number>);
({ parent: { parent: { parent: null, value: "hi" }, value: 6 }, value: "hi" } satisfies Node<string>);
function getSpecialNumber(): number {
throw "to implement!"
}
getSpecialNumber satisfies string;
void function declare_variables(Concat: <T extends string, U extends string>(a: T, b: U) => `${T}, ${U}`) {
Concat("test", "something") satisfies boolean
}
type ElementOf<T> = T extends Array<infer U> ? U : never;
void function declare_variables(elementOfNumber: ElementOf<Array<number>>, elementOfNumberOrString: ElementOf<"not array" | Array<number>>, n: never) {
elementOfNumber satisfies number;
elementOfNumberOrString satisfies string;
n satisfies ElementOf<"not array">
}
type GetPrefix<S, End> = S extends `${infer T} ${End}` ? T : false;
4 satisfies GetPrefix<"Hello Ben", "Ben">;
"hi" satisfies { length: 3 };
"hi" satisfies { length: 2 };
(() => {}) satisfies Function;
interface Wrapper<T> {
internal: T
}
({ internal: "hi" } satisfies Wrapper<number>);
({ internal: "hi" } satisfies Wrapper<string>);
const numbers1: Array<number> = [1, 2, "3"],
numbers2: Array<string> = ["hi", "3"],
numbers3: Array<string> = 4;
let c: Array<number> = []
function add() {
c.push("hi")
}
void function declare_variables(isNumber: <T>(t: T) => T extends number ? "yeess" : "nno") {
isNumber(5) satisfies "yeess";
isNumber("5") satisfies number
}
void function declare_variables(unwrap: <T>(a: T | { item: T }) => T) {
unwrap({ item: 5 }) satisfies string;
unwrap(16) satisfies 16
}
void function declare_variables(generic: <T>(a: T) => any) {
generic<string, number>("something")
}
type WithLabel<T> = { label: string, item: T };
void function declare_variables(getItem: <T>(a: WithLabel<T>) => T) {
getItem({ label: "item 1", item: 5 }) satisfies string
}
void function declare_variables(what: <T>(a: T, b: T) => T) {
what(2, 3) satisfies string
}
type Record2<K extends string, T> = { [P in K]: T };
void function declare_variables(myRecord: Record2<"hi", number>) {
myRecord.hi satisfies string;
myRecord.hello
}
void function declare_variables(obj1: Record<"hi" | "hello", boolean>) {
obj1.hi satisfies boolean;
obj1.hello satisfies boolean;
obj1.bye
}
type Mapped<T> = { [P in keyof T]: T[P] };
interface Y {
readonly a: string
b: number
}
void function declare_variables(x: Mapped<Y>) {
x.a = "hi";
x.b satisfies number
}
type Partial<T> = {
[P in keyof T]?: T[P];
};
({ a: 3 } satisfies Partial<{ a: number, b: string }>);
({ a: "hi" } satisfies Partial<{ a: number, b: string }>);
type Required<T> = {
[P in keyof T]-?: T[P];
};
({ a: 3 } satisfies Required<{ a?: number }>);
// Bad
({ } satisfies Required<{ a?: number }>);
function callFunction<T>(fn: (p: T) => void) {
// ...
}
callFunction<string>(a => {
a satisfies number;
});
function eqNarrow(a: string) {
if (a === "hi") {
a satisfies "hello"
}
}
function typeOfNarrow(param: any) {
if (typeof param === "string") {
param satisfies number;
}
}
function booleanNarrow(param: boolean) {
if (param) {
param satisfies string
}
if (!param) {
param satisfies number
}
}
function operatorNarrows(thing: string | null) {
(thing ?? "something") satisfies string;
(thing || "something") satisfies number;
const result = thing === "hi" && (thing satisfies boolean);
}
function logicNarrow(thing: any, other: any) {
if (typeof thing === "string" && other === 4) {
({ thing, other }) satisfies string;
}
if (typeof thing === "string" || typeof thing === "number") {
thing satisfies null;
}
}
function narrowPropertyEquals(param: { tag: "a", a: string } | { tag: "b", b: number }) {
if (param.tag === "a") {
param.a satisfies string;
param satisfies null;
}
}
function narrowFromTag(param: { tag: "a", a: string } | { tag: "b", b: number }) {
if ("a" in param) {
param.a satisfies string;
param satisfies null;
}
}
function buildObject(param: any) {
if ("a" in param) {
param satisfies null;
}
}
function conditional(param: boolean) {
const obj1 = { b: 2 }, obj2 = { c: 6 };
const sum = param ? obj1 : obj2;
if (sum === obj1) {
sum.a = 3;
}
[obj1, obj2] satisfies string;
}
function getName(name?: string) {
if (name) {
name satisfies undefined;
return name
} else {
return "default"
}
}
{
const obj = { a: true, b: false };
const x: { a: boolean } = obj, y: { b: boolean } = obj;
obj.a = "yo";
obj.b = "wassup";
}
{
// and in the same assignment through a cycle
const obj = { a: 2, b: 3 }; obj.c = obj;
const something: { a: number, c: { b: number } } = obj;
obj.a = "hi";
obj.b = "hello";
}
const proxy1 = new Proxy({ a: 2 }, { get(target: { a: number }, prop: string, receiver) {
if (prop === "a") {
return target["a"] + 1
}
} } );
proxy1.a satisfies string;
5 satisfies MultipleOf<2>;
4 satisfies MultipleOf<2>;
6 satisfies GreaterThan<2>;
-4 satisfies GreaterThan<2>;
2 satisfies LessThan<2>;
-3 satisfies LessThan<2>;
void function declare_variables(a: number, b: Not<5> & number) {
4 satisfies Not<4>;
6 satisfies Not<4>;
a satisfies Not<8>;
2 satisfies Not<string>;
"hi" satisfies Not<string>;
b satisfies number;
b satisfies string;
b satisfies 5
}
"Hi" satisfies CaseInsensitive<"hi">;
"Hello" satisfies CaseInsensitive<"hi">;
// yeah
type CIWord = "WORD" extends Uppercase<infer T> ? T : never;
"wOrd" satisfies CIWord;
"wood" satisfies CIWord;
};
() => {
let x: number = 3
x = "hello world"
let a = 2
a = "hello world"
a satisfies number
let b;
b satisfies string;
const my_obj: { b: 3 } = { b: 4 }
const object = {
x: 4,
get value(this: { x: number }) {
return this.x
},
}
object.value satisfies string
const obj: { a?: number, b?: number } = { a: 2 }
function setProperty(key: "a" | "b", value: number) {
obj[key] = value;
}
setProperty("b", 6)
obj satisfies string;
function func(get: () => number) {
const obj = {};
Object.defineProperty(obj, "value", { get });
obj.value satisfies string
}
function id(a) {
return a
}
const d: 3 = id(2);
function MyClass(this: { other: string }) { }
MyClass.prototype.other = 2;
const m = new MyClass();
function optionally(p?: number) {
return p
}
// Fine
optionally() satisfies undefined;
optionally(5) satisfies 5;
optionally("hello world");
void function declare_variables(b: boolean) {
let i = 0;
if (b) {
i = 1
} else {
i = 2
}
i satisfies string
}
void function declare_variables(myObject: { a: 1, b: 2, c: 3 }) {
let properties: string = "";
for (const property in myObject) {
properties += property
}
properties satisfies boolean
}
function throwType(a) {
throw a
}
try {
throwType(3)
} catch (err) {
err satisfies string
}
console.log("Error caught!");
function exceptionToResult(cb: () => number) {
try {
cb()
} catch (e: number) {
return e
}
}
exceptionToResult(() => { throw "not a number" });
console.log("Error caught!");
const value: string = 0 / 0 + 1;
const y = { ["EZNO".toLowerCase()]: 7 }
y.ezno satisfies 3
y.not_a_key
type X = { a: string }
{
interface X {
b: number
}
const x: X = { b: 3 } // Don't require 'a' here <-
const y: X = { b: "NaN" }
}
function myTag(static_parts: Array<string>, other: string) {
return { static_parts, other }
}
const name = "Ben";
myTag`${name}Hello ` satisfies string;
const regexp = /hi/;
const match = regexp.exec("hi");
match satisfies number;
match.index satisfies string;
match.input satisfies boolean;
function doThingWithClass(instance: Class) {
instance.prop satisfies string;
instance.parent_prop satisfies boolean;
instance.method(4);
}
class BaseClass {
parent_prop: number
}
class Class extends BaseClass {
prop: number
method(s: string) {}
}
function getA<T extends { a: string }>(p: T) {
return p.a
}
getA({ a: 2 });
function getProp<T extends { prop: string, other: string }>(t: T): T["prop"] {
return t.other
}
function getOther<T extends { prop: string, other: string }>(t: T): T["other"] {
return t.other
}
type Introduction = `Hello ${string}`;
const first: Introduction = "Hello Ben";
const second: Introduction = "Hi Ben";
const third: `Hiya ${string}` = "Hello Ben";
// Edge cases
const invalidNum1: `${1}` = 1;
const invalidNum2: `${1}` = "1";
const invalidNum3: `${1}` = "2";
type Immutable<T> = { readonly [P in keyof T]: T[P] };
interface Y {
a: string
}
void function declare_variables(x: Immutable<Y>) {
x.a = "hi"
}
function eqNarrow(a: string) {
const a_equals_hi = a === "hi";
if (a_equals_hi) {
a satisfies "hello"
}
}
function conditional(param: boolean) {
const obj1 = { a: 1 }, obj2 = { b: 2};
const sum = param ? obj1 : obj2;
if (param) {
sum satisfies string;
}
}
function func1(param: string | number) {
if (typeof param === "number" && param > 0) {
param satisfies number;
} else {
param satisfies null;
}
}
function func2(param: string | number | boolean) {
if (typeof param === "string" || !(typeof param === "number")) {
param satisfies undefined;
} else {
param satisfies number;
}
}
void function declare_variables(isNumber: (param: any) => asserts param is number, value: any) {
if (isNumber(value)) {
value satisfies string
}
}
const obj1 = { a: 5 };
const obj2: { prop: { a: number } } = { prop: obj1 }
obj1.a = 6;
obj1.a = "hello";
let lastSet: string = "";
const proxy1 = new Proxy({ a: 2 }, {
set(target: { a: number }, prop: string, value: number, receiver) {
lastSet = prop;
}
});
proxy1.a = 6;
lastSet satisfies boolean;
};
() => {
a = 3;
let a = 2;
let my_obj = { a: 3 }
my_obj.a = 4
let b: 3 = my_obj.a
void function declare_variables(condition: boolean) {
const obj = { foo: 1, ...(condition ? { bar: 2, non_existent: 3 } : { }) };
obj.foo satisfies number;
obj.bar satisfies string
}
void function declare_variables(key: "a" | "b") {
const object = { a: "apple", b: "banana" };
object[key] satisfies boolean
}
const x: { a?: number } = { a: 4 };
// Fine
delete x.a;
const y: { a: number } = { a: 4 };
// Bad
delete y.a;
const z = {};
Object.defineProperty(z, "a", { value: 4 });
delete z.a;
interface MyObject { property: string }
function process(param: MyObject) {}
process({ property: "hello", another: 2 });
function func<T>(a: T) { }
func<MyObject>({ property: "hello", "something else": 2 });
try {
throw 3
} catch (err: string) {
console.log(err)
}
console.log("Error caught!");
function exceptionToResult(s: string) {
try {
return JSON.parse(s)
} catch (e: number) {
return e
}
}
console.log("Error caught!");
void function declare_variables(myArray: Array<string>) {
([] instanceof Array) satisfies true;
({ } instanceof Map) satisfies 4;
class X { }
(new X instanceof X) satisfies true;
([] instanceof X) satisfies false;
function isArray(param: any): boolean {
return param instanceof Array
}
isArray([1, 2, 3]) satisfies true;
isArray(myArray) satisfies string;
isArray({ }) satisfies null
}
const regexp = /Hi (?<name>.*)/;
const match = regexp.exec("Hi Ben");
match.input satisfies number;
match.groups satisfies string;
function doThingWithClass(instance: Class) {
instance.a satisfies number;
instance.b satisfies string;
}
class BaseClass {
b: boolean
}
class Class extends BaseClass {
a: number
}
void function declare_variables(id: <T>(a: T) => T, box: <T>(a: T) => { item: T }, someNumber: number) {
id(someNumber) satisfies string;
box(someNumber) satisfies boolean
}
type Mutable<T> = { -readonly [P in keyof T]: T[P] };
interface Y {
readonly a: string
}
void function declare_variables(x: Mutable<Y>) {
x.a = 4;
x.a = "hi"
}
function eqNarrow(a: string) {
function equalsHi(p: string): boolean { return p === "hi" }
if (equalsHi(a)) {
a satisfies "hello"
}
}
function conditional(param: boolean) {
const constant = param;
if (constant) {
const b = () => constant;
b satisfies string;
}
}
function func1(param: any): asserts param is number {
if (typeof param !== "string") {
throw "bad"
}
}
function func2(param: any): asserts param is boolean {
if (typeof param !== "boolean") {
throw "bad"
}
}
const obj1 = { a: 5 };
const obj2: { prop: { a: number } } = { prop: obj1 }
obj1.a = 6;
obj1.a = "hello";
const proxy1 = new Proxy({}, { get(_target, prop, receiver) { return prop } });
proxy1 satisfies { a: "a", b: "b" };
proxy1 satisfies { c: "d" };
function makeObservable(obj, cb: (kind: string, prop: string, value: any) => void) {
return new Proxy(obj, {
get(on, prop: string, _rec) {
cb("get", prop, on[prop])
},
set(on, prop: string, _value, _rec) {
cb("set", prop, on[prop])
},
})
}
let r = null;
const value = makeObservable({ a: 1 }, (k, p, v) => {
r = { k, p, v };
});
r satisfies null;
value.a = 2;
r satisfies string;
};
() => {
const a = 2
{
const a = 3;
a satisfies 3;
}
a satisfies 2;
const a = 3;
const x = { a: 2, b: 3 }
delete x.b;
const b = x.b;
const obj = { a: 1, b: 2 };
obj.a = 2; obj.c = 6; obj.b = 4;
obj satisfies boolean;
let global: number = 0;
const object = {
get value() {
return global
},
set value(newValue: number) {
global = newValue;
}
}
object.value satisfies string;
object.value = 10;
object.value satisfies 10;
global satisfies 10
function func(a: number) {
a satisfies string
}
const regexp = /.*(?<x>[a-z]+)(?<y>[0-9]+)/;
const match = regexp.exec("ez as abc123");
match.input satisfies number;
match.groups.x satisfies "c";
match.groups.y satisfies boolean;
class X {
method() {
return this;
}
}
const { method } = new X();
method();
function eqNarrow(a: string) {
const b = a;
if (b === "hi") {
a satisfies "hello"
}
}
const my_obj: { a: number } = { a: 2 }
my_obj.a = "hello world"
};
() => {
const a = 2
{
const a = 3;
a satisfies 2;
}
let x = {}; x.something = null; x[4] = null; x["eight"] = null; x["2"] = null;
x satisfies string;
const obj = { get prop() { return 2 } };
obj.prop = "hi";
obj.prop satisfies 2;
type MyObject = { foo: number, bar: number };
void function declare_variables(condition: boolean) {
const b: MyObject = { foo: 1, ...{ bar: 2, invalid: 3 } };
const c: MyObject = { foo: 1, ...(condition ? { bar: 2, non_existent: 3 } : { }) }
}
function func(): string {
return 2
}
function MyClass(value) {
this.value = value
}
MyClass.prototype.other = 2;
const object = new MyClass("hi");
object.value satisfies "hi";
object.other satisfies "hello";
let global: number = 0;
class X {
[global++] = "b";
}
global satisfies 0;
(new X)[0] satisfies "a";
(new X, new X);
global satisfies string;
};
() => {
let my_obj = { a: 3 }
const a = my_obj.a
const b = my_obj.b
const obj = { prop: 1 };
// Fine
obj.non_existent = 6;
function func(param: { prop: number }) {
param.notProp = 5;
}
const x: 4 = 2 + 3
const y: 6 = 2 * 3
const z: 8 = (2 * 3) - 2
const object = { a: { b: { c: 2 } } }
const { a: { b: { c: d } } } = object
d satisfies 1;
let global: number = 0;
class X {
property = ++global;
}
(new X()).property satisfies string;
(new X()).property satisfies 2;
(new X()).property satisfies boolean;
};
() => {
let a = 2;
const obj = {
x: 5,
set value(this: { x: number }, v) {
this.x = v;
}
}
obj.value = "some value";
obj.x satisfies 5;
const x: 2 = 2 & 3
const y: 6 = 2 ^ 7
const z: 14 = 8 | 4
function func(a: string, b: number): boolean {
return true
}
func satisfies (a: string, b: number) => boolean;
func satisfies (a: string, b: number) => string;
func satisfies (a: number, b: number) => boolean;
let b: number = 0
function doThing(a: number = (b += 2)) {
return a
}
doThing(7);
b satisfies 0;
doThing();
b satisfies 1;
class X {
a = 2
}
(new X).a satisfies 3
};
() => {
let a = 2;
const obj = {
x: 5,
set value(v) {
a = v;
}
}
obj.value = "some value";
a satisfies 2;
const x: 2 = 3 && 2
const y: 6 = 3 && false
const z: false = true || 4
function func<T extends boolean>(condition: T) {
if (condition) {
return 4
} else {
return 3
}
}
func satisfies string;
function Closure(n: string) {
return { get value() { return n }, set value(newValue: string) { n = newValue; } };
}
let b = Closure("hi");
b.value = "something";
b.value satisfies number;
class X {
static a = 2
}
X.a satisfies 3
};
() => {
function a() { }
class B { }
let c = class { }
a.name satisfies "a"
B.name satisfies "B"
c.name satisfies "sea"
const obj = { n: 1, b: 2 };
Object.defineProperty(obj, "c", { value: 3, enumerable: false });
Object.defineProperty(obj, "d", { value: 4, enumerable: true });
let keys: string = "";
for (const key in obj) {
keys += key;
}
keys satisfies boolean
const x: (a: string) => number = a => a.to;
function func(value: number) {
if (value === 3) {
return "is three"
}
console.log("hi")
return "another"
}
func satisfies (a: number) => "is three" | "another";
function loop(value: number) {
for (let i = 0; i < 10; i++) {
if (value === i) {
return "something"
}
}
return "another"
}
loop satisfies (a: number) => "something" | "another";
function sometimes(a: boolean) {
if (a) {
return "sometimes"
}
}
sometimes satisfies (a: boolean) => string;
class X {
static x = 2;
static {
const property: 4 = ++this.x;
}
}
X.x satisfies 3;
};
() => {
const obj = {};
Object.defineProperty(obj, 'property', {
value: 42,
writable: false,
});
obj.property satisfies string;
obj.property = 70;
interface MyObject { property: string }
const a: MyObject = { property: "hello", another: 2 }
function x() {
getString(3)
}
function y() {
getString("something") satisfies string;
}
function getString(param: string): string {
return "hi"
}
function func(a: number) {}
func("hello world");
class X { a: number = 2 }
class Y { a: number = 2}
function doThingWithX(x: X) {}
doThingWithX(new X());
doThingWithX(new Y());
};
() => {
const obj = {};
Object.defineProperty(obj, 'property', {
value: 42,
enumerable: false,
// needed as all properties default to false
writable: true,
});
obj.property = 70;
Object.getOwnPropertyDescriptor(obj, 'property') satisfies string;
let a = 5, b = 6;
a++;
a satisfies 4;
b *= 4;
b satisfies 23;
function func(p1: number, p2: string) {}
func(4);
const x = "hi"
x();
type X<T> = T;
2 satisfies X<string>;
};
() => {
const obj = {};
let b = 0;
Object.defineProperty(obj, 'property', {
get: () => b,
});
obj.property satisfies 0;
b++;
obj.property satisfies string;
function func(p1: number) {}
func(4, "extra");
let a: number = 2
function runFunctionTwice(func: () => void) {
func()
func()
}
a satisfies 2
runFunctionTwice(() => { a++ })
a satisfies string
function getX() {
return x
}
getX satisfies () => number;
getX();
let x: number = 5;
type X = 2 & "hi";
type Y = string & number;
};
() => {
const obj = {};
Object.defineProperty(obj, 'property', { value: 6 });
Object.defineProperty(obj, 'property', { value: "hi" });
void function declare_variables(func: <T>(prop: { a: number, b: T, c: string } | { a: number, b: string, c: T }) => T) {
;
func({ a: 3, b: "hi", c: false }) satisfies string
}
let a: number = 2
function runFunctionTwice(func: () => void): number {
func()
const b = a
func()
return b;
}
a satisfies 2
const out = runFunctionTwice(() => { a++ });
a satisfies 4
out satisfies string
const x = [1];
x.push("hi");
x[1] satisfies 3;
x.length satisfies 4;
type X<T> = T;
const b: X = 2;
};
() => {
const obj = { a: "something" };
Object.defineProperty(obj, 'b', { value: 42 });
Object.getOwnPropertyDescriptor(obj, 'a') satisfies string;
Object.getOwnPropertyDescriptor(obj, 'b').writable satisfies false;
let a: number = 0
function func() {
a = 4;
// Important that subsequent reads use the
// new value, not the same free variable
a satisfies 4;
}
func()
let b: 2 = a
const x: Array<number> = [1]
x.push("hi");
interface X {
a: string
}
interface Y {
b: string
}
interface Z extends X, Y {
c: string
}
({ a: "", b: "", c: "hello" }) satisfies Z;
({ a: "", b: 4, c: "hello" }) satisfies Z;
({ c: "hi" }) satisfies Z;
};
() => {
const obj = { a: 1 };
Object.assign(obj, { b: 2, c: 3 });
obj satisfies string;
let a: number = 0
function func(c: number) {
a = c
}
func(4)
let b: 2 = a
interface X {
a: string,
b: boolean
}
const x: X = { a: 2, b: false }
};
() => {
const obj = {}
let result = Object.freeze(obj);
(obj === result) satisfies true;
obj.property = 2;
Object.isSealed(obj) satisfies true;
function func(obj: { prop: number }) {
return obj.prop
}
func({ get prop() { return b } });
let b: number = 0;
let a: number = 0
function conditional(v: string) {
if (v === "value") {
a++
}
}
conditional("x")
a satisfies 2
conditional("value")
a satisfies 3
getFive() satisfies 4;
function getFive() {
return 5
}
let x: X = { a: 3 }
interface X {
a: 2
}
};
() => {
const obj = { a: 2 }
let result = Object.seal(obj);
(obj === result) satisfies true;
// Allowed
obj.a = 4;
// Not allowed
obj.property = 2;
Object.isSealed(obj) satisfies true;
Object.isFrozen(obj) satisfies false;
function newObject() {
return { prop: 2 }
}
const a = newObject(), b = newObject();
const c = a;
(a === c) satisfies false;
(a === b) satisfies string;
function safeDivide(num: number, denom: number) {
if (denom === 0) {
throw new Error("Cannot divide by zero");
}
return num / denom
}
function func() {
safeDivide(8, 4) satisfies 2;
// ahh
safeDivide(10, 0);
}
const x = 2
const y = { x }
y.x satisfies 3
interface X {
a: string,
b: string
}
"a" satisfies keyof X; "b" satisfies keyof X; "c" satisfies keyof X;
};
() => {
const obj = { a: 2 }
let result = Object.preventExtensions(obj);
(obj === result) satisfies true;
// Allowed
obj.a = 4;
// Not allowed
obj.property = 2;
Object.isFrozen(obj) satisfies false;
Object.isSealed(obj) satisfies false;
let x: number = 2;
function func(cb: () => void) {
try {
cb();
x = 10;
return "not-thrown"
} catch {
return "thrown"
}
}
func(() => { throw "error" }) satisfies "thrown";
x satisfies string;
let a = false, b = 4;
a ||= b++;
a satisfies 3;
b ||= (b = 10);
b satisfies string;
type X<T> = T extends { a: infer I extends string } ? I : string;
void function declare_variables(a: X<{ a: 4 }>, b: X<{ a: "hello" }>) {
a satisfies number;
b satisfies "hello"
}
};
() => {
const obj = {
a: 4,
getA(this: { a: any }) {
return this.a
}
}
obj.a = 5;
obj.getA() satisfies 6;
let value: number = 2;
function a() { value = 8; }
function b() { a() }
let func = () => {};
function c() { b() }
function d(newCb: () => void, then: () => void) { func = newCb; then() }
value satisfies 2;
d(a, c);
value satisfies boolean;
interface BoxString<T extends string> {
inner: T
}
let x: BoxString<string, number>;
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
interface X {
a: number
b: string
c: string
}
void function declare_variables(y: Pick<X, "b" | "c">) {
({ a: 5 } satisfies Pick<X, "a">);
({ a: 5 } satisfies Pick<X, "a" | "b">);
({ a: 5, b: "hi" } satisfies Pick<X, "a" | "b">);
({ a: 5, b: 6 } satisfies Pick<X, "a" | "b">);
y.b satisfies string;
y.a
}
};
() => {
const obj: { a: number } = { a: 2 }
function func(value: number) {
obj.a = value
}
obj.a satisfies 2
func(4)
obj.a satisfies 3
let a: number = 1, i: number = 0;
while (i < 5) {
a *= 2;
i++;
}
a satisfies 8;
const x: "\"" = '"';
const y: "Hi" = `Hello\``;
type PrefixKeys<T> = { [P in ((keyof T) & string) as `property_${P}`]: T[P] };
interface X {
a: number
}
void function declare_variables(x: PrefixKeys<X>) {
x.property_a satisfies number;
x.property_b
}
};
() => {
function add_property(obj: { prop: number }) {
obj.prop += 2;
}
const obj = { prop: 4 };
add_property(obj);
obj.prop satisfies 8;
function func(a: number, b: number) {
return class {
value: number;
constructor() {
this.value = a;
}
plusB() {
return this.value + b
}
}
}
const c1 = new (func(1, 2));
c1.plusB() satisfies 3;
const c2 = new (func(6, 8));
c2.plusB() satisfies string;
let a: number = 1, i: number = 0;
while (i++ < 5) {
a *= 2;
}
a satisfies 8;
class X {
constructor(value) {
this.value = value
}
}
const x = new X(4)
x.value satisfies string
};
() => {
function dewete(param: { prop?: string }) {
const { prop } = param;
delete param.prop;
return prop
}
const obj = { prop: "hi" };
dewete(obj);
obj.prop;
let a: number = 0
const func = condition => condition || ++a;
func(true);
a satisfies 0;
func(false) satisfies 1;
a satisfies 2;
let global: number = 0;
class X {
prop1 = ++global;
constructor() {
this.prop2 = ++global;
}
}
const x = new X();
x.prop1 satisfies string;
x.prop2 satisfies boolean;
};
() => {
function func(param: boolean) {
let a = 2;
if (param) {
a = 3;
return a;
} else {
a = 7;
}
a satisfies string;
}
let a: number = 0;
do {
a++
} while (a < 3)
a satisfies 8;
const obj = { a: 2 };
("a" in obj) satisfies string;
("b" in obj) satisfies true;
class X {
constructor(value) {
this.value = value
}
getObject(this: { value: any }, b) {
return { a: this.value, b }
}
}
const x = new X(4)
x.getObject(2) satisfies string
};
() => {
let a: string = "";
for (let i: number = 0; i < 10; i++) {
a = a + i;
}
a satisfies number;
void function declare_variables(x: NotNotANumber) {
// True regardless of
function func(a: number) {
return a ** 0
}
func satisfies string;
(x ** 1 === x) satisfies true
}
const x = new X;
class X { }
const obj = { a: 1, b: 2, c: 3 };
obj satisfies { [s: string]: number };
obj satisfies { [s: string]: boolean };
};
() => {
void function declare_variables(i: number) {
let a: number = 0;
while (a < i) {
a++
}
a satisfies string
}
function func(a: number, b: boolean) {
const x = !a;
const y = ~b;
(!b), (~a);
}
class X { }
const x = X();
function func1(p: { a: string, b: string }) {
func2(p)
}
function func2(p: readonly { a: string }) { }
const obj = Object.freeze({ a: "hi" });
func2(obj);
};
() => {
let a: number = 0;
while (a++ < 1_000_000) {}
a satisfies string;
void function declare_variables(someNumber: number) {
function func() {}
(typeof 5) satisfies "number";
(typeof "hi") satisfies "string";
(typeof func) satisfies "function";
(typeof someNumber) satisfies "function"
}
let b: number = 0;
class Y {
constructor(a) {
this.a = a;
b++;
}
}
class X extends Y {
constructor(a) {
super(a);
}
}
const x = new X("hi");
x.a satisfies "hello";
b satisfies 1;
interface MyObject {
a(b: string): any;
}
const obj: MyObject = {
a(b) {
b satisfies number;
}
}
};
() => {
let a: number = 2, i: number = 0;
while (i++ < 10) {
a *= 2;
if (a > 5) {
break;
}
}
a satisfies 2;
interface X {
a: string
b: string
}
function func(x: X | null) {
x.a;
x?.b satisfies number;
}
// Perfectly fine
const x: (a: number) => string = (p: string | number) => "hi"
// Bad
const y: (a: number | string) => string = (p: number) => "hi"
const obj = { a: 2 };
const proxy1 = new Proxy(obj, { });
proxy1.a = 6;
obj.a satisfies 6;
proxy1.a satisfies string;
};
() => {
let a: number = 2, i: number = 0;
while (i++ < 10) {
if (i % 2) {
continue;
}
a *= 2;
}
a satisfies 2;
type X = string;
{
type X = number;
const a: X = "hello world";
}
function func<YEA>() {}
type B = YEA;
// Perfectly fine
const x: (a: number, b: string) => string = (p: number) => "hi"
// Bad
const y: (a: string) => string = (p: number, q: string) => "hi"
};
() => {
const object = { a: 1, b: 2 }
const { a, b } = object
a satisfies 1; b satisfies string;
const x: (a: number) => number = p => 4;
const y: (a: number) => number = p => "a number"
void function declare_variables(func: <T>() => T | string) {
func<number>() satisfies string | number;
func<never>() satisfies boolean
}
interface X {
a: number
b: X
}
const myObject = { a: 2 };
myObject satisfies X;
myObject.b = myObject;
myObject satisfies X;
};
() => {
const o = { a: 1, b: { c: 3 } };
let a, b, d;
({
d = o.a++,
b: { c: b = 7 },
a,
} = o);
a satisfies string;
b satisfies boolean;
d satisfies 3;
type X = Y;
type Y = X;
// test usage doesn't blow up subtyping
const x: X = 2;
function func(a: `a${string}`, b: `b${string}`, c: string) {
const res1 = a === b;
const res2 = (b === c) satisfies string;
}
};
() => {
type X = number;
const a: Y = 2;
void function declare_variables(func: <T>(a: T, b: NoInfer<T>) => T) {
func("hi", "hello") satisfies number
}
const x: Record<"test", boolean> = { no: false },
y: Record<"test", boolean> = { test: 6 },
z: Record<"test", boolean> = { test: false };
};
() => {
type X = number;
const a: X<number> = 2;
function func<T>(a: T) {}
func<number>("hello world");
function x(p: { readonly a: string, b: string }) {
p.a = "hi";
p.b = "hi";
}
};
() => {
const a: Uppercase<"something" |"hi"> = "HI";
const b: Uppercase<string> = "hi"
void function declare_variables(func: () => any) {
func<string>()
}
const x = [1, 2, 3];
x.map(a => (a satisfies string, 2));
};
() => {
function func(param: boolean | string | number) {
if (typeof param === "boolean") {
return 5
}
param satisfies null;
}
const x = { a: 3 };
Object.setPrototypeOf(x, { a: 5, b: 2 });
x.a satisfies 3;
x.b satisfies string;
const obj = Object.setPrototypeOf(
{},
Math.random() ? { a: 2 } : { get a() { return 0 } }
);
const result = 'a' in obj;
result satisfies string;
};
() => {
function func(param: Array<string> | string) {
if (param instanceof Array) {
param satisfies null;
}
}
const x = { a: 3 };
const p = { b: 2 }
Object.setPrototypeOf(x, p);
const p_of_x = Object.getPrototypeOf(x);
// ('a' in p_of_x.a) satisfies false;
(p === p_of_x) satisfies string;
};
() => {
function func(param: any) {
if (param instanceof Array) {
param satisfies null;
}
}
const x: string = 5;
const y: string = h;
function getString(a: number): string {
return a
}
x satisfies string;
y satisfies string;
const z: number = getString(2);
};
() => {
function func(param: boolean) {
let a = param;
const inner = (value: boolean) => a = value;
if (a) {
inner(false);
a satisfies null;
}
}
const obj = { prop: 2 };
console.log(obj.a.b.c);
function x() {
return y
}
x().nothing
};
() => {
function func(param: number | Array<string>) {
if (Array.isArray(param)) {
param satisfies null;
}
}
function JSXH(tag_name: string, attributes: any, children: any) {
return { tag_name, attributes, children }
}
const x = <h1 title="Example text">Hello World</h1> satisfies string;
};
() => {
function func(param: number) {
if (param !== param) {
param satisfies string;
}
// Derives from `!==`
if (Number.isNaN(param)) {
param satisfies null;
}
}
function x(a /** string */) {
a satisfies number
}
const c /** number */ = "hello"
};
() => {
function func(a: boolean) {
const x = a ? 1 : 2;
if (x === 1) {
a satisfies "hi"
}
}
interface X { a: number }
const x = { a: 1, b: 2 };
x satisfies Exclusive<X>;
({ a: 6 } satisfies Exclusive<X>);
};
() => {
function func(value: any) {
function isNumber() { return typeof value === "number" }
if (isNumber()) {
value satisfies string
}
}
};
() => {
function register(a: Literal<string>) {
// ...
}
register("something")
// `document.title` is an unknown string, non-literal
register(document.title);
function func(param: object) {
const obj = { a: 2 };
const obj1: Literal<object> = obj;
const obj2: Literal<object> = param;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment