Typed Flags

Generate TypeScript types for your feature flags with the FastStats CLI

The FastStats CLI can generate a declaration file from your project’s flags. With it, the browser SDK knows every key and the values each flag can serve:

flags.get("theme", "system"); // "light" | "dark" | "system"
flags.get("new-chekout", false); // Error: not a flag in this project
flags.isEnabled("theme"); // Error: not a boolean flag
useFlag("theme", true); // Error: theme serves strings

Types are optional. Without the file, any key is accepted and the result is typed by the default you pass.

Generate the File

Install the CLI and sign in once:

npm install -g @faststats/cli
faststats login

Then generate the types from your project root:

faststats flags typegen your-project-slug

This writes src/faststats-flags.d.ts, or faststats-flags.d.ts when there is no src/ folder. Make sure your tsconfig.json includes it. Pass --output (-o) to put it somewhere else:

faststats flags typegen your-project-slug --output types/flags.d.ts

Commit the file. Run the command again after you add or change flags.

What Gets Generated

src/faststats-flags.d.ts
// Generated by `faststats flags typegen your-project-slug`. Do not edit.
// Run it again after changing flags; `--check` fails while this file is stale.

export {};

declare global {
	interface FastStatsFeatureFlags {
		/**
		 * New checkout
		 *
		 * @see https://faststats.dev/project/your-project-slug/feature-flags/flag/…
		 */
		"new-checkout": boolean;
		/**
		 * Theme
		 *
		 * Site color scheme.
		 *
		 * @see https://faststats.dev/project/your-project-slug/feature-flags/flag/…
		 */
		theme: "dark" | "light";
		"max-uploads": 10 | 50;
		banner: { readonly text: string; readonly link: string };
	}
}
Flag typeGenerated type
Booleanboolean
StringThe variants’ values, such as "dark" | "light"
NumberThe variants’ values, such as 10 | 50
JSONThe variants’ shape, with strings, numbers, and booleans widened

Each flag’s name, description, and a link to it in the dashboard show up when you hover the key in your editor.

Archived flags are left out, so code that still reads one fails to compile. That makes cleaning up old flags a matter of fixing the errors.

Defaults and Return Types

The default is part of the result type, because it is what a read returns until flags load:

const theme = flags.get("theme", "system"); // "light" | "dark" | "system"
const limit = flags.get("max-uploads", 0); // 10 | 50 | 0

A default must match the flag’s type, but it does not have to be one of its variants.

Check in CI

--check compares the file with the project’s current flags without writing anything. It exits with an error when the file is missing or out of date.

faststats flags typegen your-project-slug --check

CI cannot use faststats login. Set FASTSTATS_API_KEY to an API key with access to the project instead:

.github/workflows/ci.yml
- run: npx @faststats/cli flags typegen your-project-slug --check
  env:
    FASTSTATS_API_KEY: ${{ secrets.FASTSTATS_API_KEY }}

List Flags

faststats flags list shows each flag’s key, status, and the values it serves. Add --archived to include archived flags.

faststats flags list your-project-slug