The keyof operator lets code choose a property name while keeping the result type connected.

Keyof and Indexed Access

keyof.ts
type Course = {
    title: string;
    minutes: number;
    complete: boolean;
};

function getValue<T, K extends keyof T>(object: T, key: K): T[K] {
    return object[key];
}

const field: keyof Course = ;
const course: Course = { title: "Generics", minutes: 25, complete: false };
const value: Course[typeof field] = getValue<Course, typeof field>(course, field);

console.log(`${field}=${value}`);
type Course = {
    title: string;
    minutes: number;
    complete: boolean;
};

function getValue<T, K extends keyof T>(object: T, key: K): T[K] {
    return object[key];
}

const field: keyof Course = ;
const course: Course = { title: "Generics", minutes: 25, complete: false };
const value: Course[typeof field] = getValue<Course, typeof field>(course, field);

console.log(`${field}=${value}`);
type Course = {
    title: string;
    minutes: number;
    complete: boolean;
};

function getValue<T, K extends keyof T>(object: T, key: K): T[K] {
    return object[key];
}

const field: keyof Course = ;
const course: Course = { title: "Generics", minutes: 25, complete: false };
const value: Course[typeof field] = getValue<Course, typeof field>(course, field);

console.log(`${field}=${value}`);
keyof `keyof` creates a union of the property names from an object type.