Designs complex generic types, refactors `any` types to strict alternatives, creates type guards and utility types, and resolves TypeScript compiler errors. Use when the user asks about TypeScript (TS) types, generics, type inference, type guards, removing `any` types, strict typing, type errors, `infer`, `extends`, conditional types, mapped types, template literal types, branded/opaque types, or utility types like `Partial`, `Record`, `ReturnType`, and `Awaited`.
97
97%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
as const and typeofThe combination of as const and typeof is one of the most powerful patterns in TypeScript for deriving types from runtime values. This pattern allows you to create a single source of truth that works at both runtime and compile time.
as const Assertionas const is a const assertion that makes an object deeply readonly and infers literal types instead of widened types.
// Without as const - types are widened
const config = {
GROUP: "group",
ANNOUNCEMENT: "announcement",
};
// Type: { GROUP: string; ANNOUNCEMENT: string }
// With as const - literal types are preserved
const config = {
GROUP: "group",
ANNOUNCEMENT: "announcement",
} as const;
// Type: { readonly GROUP: "group"; readonly ANNOUNCEMENT: "announcement" }as constconst routes = ["home", "about", "contact"] as const;
// Type: readonly ["home", "about", "contact"]
// Without as const: string[]typeofUse typeof to extract the type from a runtime value:
const programModeEnumMap = {
GROUP: "group",
ANNOUNCEMENT: "announcement",
ONE_ON_ONE: "1on1",
SELF_DIRECTED: "selfDirected",
} as const;
// Extract the type of the object
type ProgramMap = typeof programModeEnumMap;
// Extract keys as a union type
type BackendProgram = keyof typeof programModeEnumMap;
// Type: "GROUP" | "ANNOUNCEMENT" | "ONE_ON_ONE" | "SELF_DIRECTED"
// Extract values as a union type using indexed access
type FrontendProgram = typeof programModeEnumMap[keyof typeof programModeEnumMap];
// Type: "group" | "announcement" | "1on1" | "selfDirected"Obj[keyof Obj] for Object ValuesThis pattern is like Object.values() for the type world:
const statusCodes = {
OK: 200,
CREATED: 201,
BAD_REQUEST: 400,
NOT_FOUND: 404,
} as const;
type StatusCode = typeof statusCodes[keyof typeof statusCodes];
// Type: 200 | 201 | 400 | 404You can select a subset of values by using a union of specific keys:
const programModeEnumMap = {
GROUP: "group",
ANNOUNCEMENT: "announcement",
ONE_ON_ONE: "1on1",
SELF_DIRECTED: "selfDirected",
} as const;
type ProgramMap = typeof programModeEnumMap;
// Select only individual program types
type IndividualProgram = ProgramMap["ONE_ON_ONE" | "SELF_DIRECTED"];
// Type: "1on1" | "selfDirected"as constWithout as const, you lose literal type inference:
// BAD - values are widened to string
const colors = {
RED: "#ff0000",
GREEN: "#00ff00",
};
type Color = typeof colors[keyof typeof colors]; // string
// GOOD - literal types preserved
const colors = {
RED: "#ff0000",
GREEN: "#00ff00",
} as const;
type Color = typeof colors[keyof typeof colors]; // "#ff0000" | "#00ff00"as const makes objects readonly - attempting to mutate will cause a compile error:
const config = {
timeout: 5000,
} as const;
config.timeout = 10000; // Error: Cannot assign to 'timeout' because it is a read-only property// Single source of truth for HTTP methods
const HTTP_METHODS = {
GET: "GET",
POST: "POST",
PUT: "PUT",
DELETE: "DELETE",
PATCH: "PATCH",
} as const;
type HttpMethod = typeof HTTP_METHODS[keyof typeof HTTP_METHODS];
// Type: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"
type SafeMethod = typeof HTTP_METHODS["GET"];
// Type: "GET"
type MutatingMethod = typeof HTTP_METHODS["POST" | "PUT" | "DELETE" | "PATCH"];
// Type: "POST" | "PUT" | "DELETE" | "PATCH"
function makeRequest(method: HttpMethod, url: string): void {
// method is type-safe
}
makeRequest(HTTP_METHODS.GET, "/api/users"); // OK
makeRequest("INVALID", "/api/users"); // Error