REUSABLE TYPES · LESSON 13 OF 24
Literal objects, satisfies and enums
Keep precise values while checking a configuration contract.
- as const
- satisfies
- enum
- literal unions
Your runnable checkpoint
Extract into a new practice folder. Each download includes complete source, package.json, tsconfig.json and an offline lesson. Use Node.js 22 or 24. Each checkpoint is independent.
Install with npm install. Run npm run check, then npm run build. Terminal lessons use npm start; browser lessons use npm run serve and http://127.0.0.1:4173.
1. Understand the concepts
as const gives literal expressions narrow literal types and readonly properties. It is not Object.freeze and does not deeply freeze referenced objects at runtime.
satisfies checks that an expression is compatible with a target type without replacing its resulting type with that target. Combining it with as const is useful for configuration that should retain exact literals.
Enums create named constants and usually emit a runtime object. String enums give readable runtime values. A literal union or const object often works well when you want JavaScript-shaped code and easy data interchange.
Do not confuse a checked configuration with checked input. A parsed server response still needs runtime validation, even if you cast it to the type of this configuration.
2. Build and run
These are complete files. Preserve the paths shown below, including the src directory. The package and compiler configuration are included at the end.
src/main.ts
type Route = { path: string; method: "GET" | "POST" };
const routes = {
list: { path: "/tasks", method: "GET" },
create: { path: "/tasks", method: "POST" }
} as const satisfies Record<string, Route>;
enum Priority { Low = "low", High = "high" }
const selected: "GET" = routes.list.method;
console.log(selected);
console.log(Priority.High);
package.json
{
"name": "edupoly-typescript-literal-objects-satisfies-enums",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"check": "tsc --noEmit",
"build": "tsc",
"start": "node dist/main.js"
},
"devDependencies": {
"typescript": "5.9.3"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": [
"ES2022",
"DOM"
],
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noEmitOnError": true,
"verbatimModuleSyntax": true,
"rootDir": "src",
"outDir": "dist",
"sourceMap": true,
"types": [],
"moduleDetection": "force"
},
"include": [
"src/**/*"
]
}
3. Trace the code and check the result
- satisfies rejects a misspelled method such as GTE.
- as const retains GET instead of widening it to string.
- Priority.High is a runtime value; a union alias would be erased.
Expected result
GET
high4. Practice independently
Add a delete route and make the method contract accept it.
Show the explanation
Add "DELETE" to Route["method"], then add a delete entry. Without updating the contract, satisfies should report an error.
When something goes wrong
If tsc is missing, run npm install in the folder containing package.json. If the output looks old, rebuild before running. Read the first compiler diagnostic and check the indicated field or argument. For module errors, preserve the .js extensions in imports. Browser examples must run through the included local server, not directly as TypeScript files.
