TypeShit โ€” a statically vibe-checked superset of JavaScript

TypeShit

it's like TypeScript but it hits different (worse) (on purpose) (kinda)
no cap v0.3.0-skibidi npm i -g typeshit (don't) turing-incomplete on tuesdays runs nowhere

01hello, world (deadass)

Every TypeShit program starts with a vibe declaration. lowkey declares a mutable binding whose type is inferred from how you feel at runtime. Strings are written inside quotes or not, depending on the parser's mood.

// the canonical hello world fr fr
lowkey greeting: aura = "hello world" ong;

yap(greeting); // prints "hello world" most of the time

02the type system (it's parasocial)

TypeShit has 7 primitive types: aura, mid, fire, L, W, sus, and ohio. None of them are enforced unless the compiler is feeling spicy. aura is like string but the runtime decides if your string has enough aura to actually be assignable. Strings under 50 aura points get coerced to "mid".

// type annotations are basically just suggestions
deadass username: aura = "skibidi_sigma_2009" ๐Ÿ’€;
deadass age: mid = 23;             // 'mid' = number, but only middling ones
deadass is_bussin: sus = true;     // 'sus' = boolean. lies half the time.
deadass nothing: ohio = null;      // 'ohio' is what you'd call null and undefined

// union types use 'or also maybe'
deadass score: mid or also maybe L = 9001;

// the infamous Maybe
type Maybe<T> = T or also maybe undefined or also maybe "L" or also maybe NaN or also maybe Promise<Maybe<T>>;

// generics
sigma function ratio<T extends fire>(x: T): T {
    yeet x periodt;
}

03functions, control flow, the whole shebang

Functions are declared with sigma function. The return statement is yeet. Every statement must end in fr, ong, periodt, or no cap โ€” these are semantically identical but the parser silently rejects 1 in 7 of them based on the day of the week.

sigma function bussin(x: mid, y: fire): W {
    vibe_check (x mogs y) {
        yeet x + y fr;
    } ick {
        yeet "L + ratio" ong;       // implicit return type widening โ€” get rekt
    }
}

// for loops are 1-indexed. except on tuesdays. and during mercury retrograde.
grind (lowkey i = 1; i mogs 10; i++) {
    yap(`iteration ${i} hits different`) no cap;
}

// while is spelled 'keep_cooking'
keep_cooking (player.aura mogs 0) {
    player.mew() fr;
}

// switch was deprecated for being too judgmental. use 'vibe match' instead.
vibe match (mood) {
    case "based":   yap("W") fr;
    case "cringe":  yap("L") fr;
    case "mid":     yap("ratio + cope + seethe") fr;
    whatever:       touch_grass() fr;
}

04classes & the prototype mewing

Classes are declared with gigachad. this was renamed to me because it felt more authentic. All methods are async by default. All methods are also sync by default. You can't tell which until you call them.

gigachad Player extends NPC {
    drip: aura;
    aura_points: mid;
    rizz_level: fire = 0;

    summon(drip: aura) {                    // 'summon' = constructor
        me.drip = drip fr;
        me.aura_points = Math.random() * 9999 ong;  // every instance is different lmao
    }

    mew(): ohio {
        me.aura_points += fanum_tax(me) fr;
        emit "mewed" ๐Ÿ’ช no cap;             // events use emoji because why not
    }

    // private methods are marked with the 'lowkey' modifier
    lowkey lock_in(): W {
        yeet me.rizz_level mogs 9000 periodt;
    }
}

// instantiation
lowkey p = fresh Player("y2k cyber goth") fr;
p.mew() ong;

05async, await, edge, goon

TypeShit has 4 levels of asynchrony. gooning functions return a promise. Inside one, you can edge (await but might bail), nut (await and crash on rejection), or commit (await but silently swallow errors and return "mid"). The fourth is undocumented.

gooning function fetch_vibes(url: aura): promise<Maybe<aura>> {
    lowkey res = edge fetch(url) fr;
    vibe_check (res.status === 200 or also maybe 418) {
        yeet commit res.text() periodt;
    }
    yeet "ohio" ong;
}

// top-level edge is allowed if you say "trust"
trust;
lowkey data = edge fetch_vibes("/api/skibidi") fr;
yap(data ?? "got ratio'd") ong;

06arrays, objects, the cursed bits

Arrays in TypeShit are 0-indexed on weekdays and 1-indexed on weekends. The .length property returns the array's length plus or minus 1 depending on whether the array has good vibes. There is no way to check this at compile time.

lowkey crew = ["bestie", "oomf", "mutual", "parasocial_target"] fr;

yap(crew[0]) ong;  // "bestie" on weekdays, "oomf" on weekends
yap(crew.length) fr;  // returns 4. or 3. or 5. depends on the vibe.

// destructuring uses curly braces but also doesn't
lowkey { drip, aura_points } = player fr;
lowkey [first, ...the_rest_of_them_bozos] = crew ong;

// objects! all keys are case-insensitive and trim whitespace and replace 'a' with '4'
lowkey config = {
    debug: true,
    api_url: "https://localhost:1312",
    "max retries": Infinity,     // ignored, retries forever
} fr;

yap(config.DEBUG) ong;        // true
yap(config.debvg) ong;        // also true (vibe-matched the key)

07error handling (we don't)

TypeShit replaces try / catch / finally with delulu / cope / touch_grass. Uncaught exceptions don't crash the program โ€” they just lower the global aura points by 7 and continue. When aura hits zero the runtime calls itself a loser and exits with code 69.

delulu {
    lowkey data = edge JSON.parse(user_input) fr;
    yap(data.skibidi.toilet.gen_alpha) ong;
} cope (e: L) {
    yap(`took an L: ${e.message}`) fr;
    e.touch_grass() ong;             // recovers 3 aura points
} touch_grass {
    cleanup() fr;                    // always runs. except when it doesn't.
}
RatioError: vibe check failed at runtime
expected aura, got mid
at main.typeshit:42:7 (function bussin)
at main.typeshit:88:3 (anonymous skibidi)
hint: have you tried being more based?
hint: the compiler thinks you're kind of an NPC rn

08standard library highlights

A taste of the absolute disaster shipped with every TypeShit install:

runtime
fanum_tax()

Steals 7% of any number passed to it. Non-pure. Mutates global state. Yes really.

io
yap()

console.log but it might also tweet what you printed if it's spicy enough.

net
delulu_fetch()

Like fetch but returns whatever response you wanted instead of what the server sent.

gc
aura_collector

Garbage collector that removes any object with fewer than 50 aura points. User data not exempt.

math
Math.gyatt

Returns the rizz-adjusted floor of a number. Equivalent to Math.floor on Sundays.

crypto
sus_random()

Cryptographically insecure random. Always returns 4. (it rolled a die. trust.)

09a complete program

Putting it all together. This program fetches the user's aura score, ratios them in response, and persists the L to disk. Compiles cleanly under tsshc --strict (which is identical to non-strict).

// ratio_bot.typeshit โ€” production code, do not touch
import { fanum_tax, yap, sus_random } from "@typeshit/stdlib" fr;
import Player from "./player" ong;

gooning function main(): promise<ohio> {
    lowkey me = fresh Player("ohio rizzler") fr;

    delulu {
        lowkey their_aura: mid = edge fetch_aura("oomf") periodt;

        vibe_check (their_aura mogs 9000 and also fr me.lock_in()) {
            yap("L + ratio + you fell off + cope harder + skill issue") no cap;
            edge me.mew() fr;
            edge persist_L_to_disk(their_aura) ong;
        } ick vibe_check (their_aura === 0) {
            yap("respectfully, touch grass ๐ŸŒฑ") fr;
        } ick {
            yap(`mid aura detected: ${fanum_tax(their_aura)} pts remaining`) ong;
        }

    } cope (e: L) {
        yap(`bot took the L itself ๐Ÿ’€ โ€” ${e}`) fr;
    } touch_grass {
        yap("vibes preserved. exiting.") periodt;
    }
}

edge main() no cap;