Lab 03: Conditional & Mapped Types
Step 1: Environment Setup
docker run -it --rm node:20-alpine sh
apk add --no-cache curl
npm install -g typescript ts-node
mkdir lab03 && cd lab03
echo '{"compilerOptions":{"module":"commonjs","target":"es2020","strict":true}}' > tsconfig.jsonStep 2: DeepPartial and DeepReadonly
// types.ts
type DeepPartial<T> = T extends object
? { [P in keyof T]?: DeepPartial<T[P]> }
: T;
type DeepReadonly<T> = T extends object
? { readonly [P in keyof T]: DeepReadonly<T[P]> }
: T;
interface Config {
host: string;
port: number;
options: {
timeout: number;
retries: number;
ssl: { cert: string; key: string };
};
}
// DeepPartial: all nested props optional
const partial: DeepPartial<Config> = {
host: 'localhost',
options: { timeout: 5000 }, // ssl and retries optional too!
};
// DeepReadonly: all nested props readonly
const frozen: DeepReadonly<Config> = {
host: 'prod.server.com',
port: 443,
options: { timeout: 30000, retries: 3, ssl: { cert: 'cert.pem', key: 'key.pem' } },
};
// frozen.host = 'other'; // Error: Cannot assign to 'host' because it is a read-only propertyStep 3: DeepRequired
Step 4: Flatten
Step 5: UnionToIntersection
Step 6: OmitNever and PickByValue
Step 7: Combining Utilities
Step 8: Capstone — Type Utility Library
Summary
Utility
Pattern
Use Case
Last updated
