M Logo
๐Ÿ“ TypeScript from Zero ยท Part 40 of 50

TypeScript keyof, typeof and Indexed Access Types (T[K]) Explained

November 6, 2026

Welcome to episode 40 of TypeScript from Zero, a series for complete beginners (no JavaScript needed). Welcome back to TypeScript from zero! This is Part 5: advanced types. Types are not only for annotations. We can compute new types from values and from other types. Today three tools: type of, key of, and indexed access. A new file called keys.ts in the tasks project. Every code block below is the exact code and output from the video, ready to copy.

Setup

We start in the terminal and open the project in VS Code:

bash
cd tasks
touch src/keys.ts
code .

1. typeof

In a type position, type of takes a value, and gives its type. We have a config object with three fields. Type of config is a type that is exactly this shape. We never wrote it by hand, and it cannot go out of date.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
text
$ node src/keys.ts
{ host: 'localhost', port: 3000, debug: true }

2. keyof

Key of takes a type, and gives the union of its keys, as text types. How can we see it? We make a mistake on purpose: a variable of type config key, with the value name. tsc answers with the list: host, port and debug. TS2322.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
const k: ConfigKey = "name";
text
$ npx tsc --noEmit
src/keys.ts:5:7 - error TS2322: Type '"name"' is not assignable to type '"debug" | "host" | "port"'.

5 const k: ConfigKey = "name";
        ~

Found 1 error in src/keys.ts:5

3. Fix

We delete the line, and tsc is quiet again.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
bash
$ npx tsc --noEmit

4. Indexed access

Square brackets with a key name, in a type, read the type of one property. Config of port is number. Again we check it with a mistake: a text where a number is expected. The error says: type string is not assignable to type number.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
type PortType = Config["port"];
const p: PortType = "3000";
text
$ npx tsc --noEmit
src/keys.ts:6:7 - error TS2322: Type 'string' is not assignable to type 'number'.

6 const p: PortType = "3000";
        ~

Found 1 error in src/keys.ts:6

5. Fix

We delete it as well.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
type PortType = Config["port"];
bash
$ npx tsc --noEmit

6. Together

The three tools together make a safe getter. The key parameter must be a key of config, and the result type is config indexed by that same key. So getting the port gives a number, and getting the host gives a string. The type follows the key.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
type PortType = Config["port"];
function getValue<K extends keyof Config>(key: K): Config[K] {
  return config[key];
}
console.log(getValue("port"), getValue("host"));
text
$ node src/keys.ts
{ host: 'localhost', port: 3000, debug: true }
3000 localhost

7. Error

A key that does not exist, like colour, is an error, and the message lists the allowed keys. TS2345. A typo in a key can not slip through.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
type PortType = Config["port"];
function getValue<K extends keyof Config>(key: K): Config[K] {
  return config[key];
}
console.log(getValue("port"), getValue("host"));
console.log(getValue("colour"));
text
$ npx tsc --noEmit
src/keys.ts:10:22 - error TS2345: Argument of type '"colour"' is not assignable to parameter of type '"debug" | "host" | "port"'.

10 console.log(getValue("colour"));
                        ~~~~~~~~

Found 1 error in src/keys.ts:10

8. Fix

We delete the line, and everything is quiet.

src/keys.ts:

ts
const config = { host: "localhost", port: 3000, debug: true };
type Config = typeof config;
console.log(config);
type ConfigKey = keyof Config;
type PortType = Config["port"];
function getValue<K extends keyof Config>(key: K): Config[K] {
  return config[key];
}
console.log(getValue("port"), getValue("host"));
bash
$ npx tsc --noEmit

Recap

Today: type of for the type of a value, key of for the keys of a type, indexed access for the type of one property, and all three in one safe function. Next episode: mapped types.

ยฉ 2026 All Rights Reserved By Mahmudul Alam