How to safely refer to a parameterised property of an object in Typescript?

Viewed 32

I have a function that receives an object as parameter and accesses one of its properties, determined by another parameter. Something like this:

// js code
function setProperty(subject, property, value) {
    subject[property] = value;
}

How do I type-annotate this function in a way that makes sure the property param is a key of the subject param, and the value param has the same type?

If it helps, I expect the property param to always be a literal value (a "hard coded" value, not a variable), so that's an acceptable constraint.

1 Answers

You can use generics, extends, and keyof to achieve this sort of functionality. For example:

interface Subject {
    a: string,
    b: number
}

function setProperty<T extends keyof Subject>(subject: Subject, property: T, value: Subject[T]) {
    subject[property] = value;
}

const test: Subject = { a: 'test', b: 2 };

setProperty(test, 'b', 'test'); // Won't compile: Argument of type 'string' is not assignable to parameter of type 'number'.
Related