Reputation: 723
I was going over the documentation on Advanced Types in Typescript (found here: https://www.typescriptlang.org/docs/handbook/advanced-types.html) and it mentioned the Index Query Operator and gave the following as an example:
function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
I understand how keyof
produces a union of all known public property names on object T
but I don't exactly understand what role the extends
plays. I get that it's saying that K
must be a valid property of T
but why is extends
used and not something else? Also, is it possible to extend unions in Typescript or is this more of a semantic specific to generics?
Thanks.
Upvotes: 5
Views: 483
Reputation: 106660
The keyword extends
, in this context, is a way to add a constraint on a type parameter.
Given this simple example, you will see the compiler only allows you to pass in objects that conform to the Person
interface:
interface Person {
name: string;
}
function logAndReturnPerson<T extends Person>(person: T) {
console.log(person.name);
return person;
}
// ok
const result1 = logAndReturnPerson<Person>({ name: "David" });
// not ok, string does not satisfy constraint of Person
const result2 = logAndReturnPerson<string>("");
In your example, K extends keyof T
means that K
is constrained to keyof T
. In other words, this means what you thought—K
is a string that is constrained to be a property name of T
.
Yes, this is a semantic specific to generics. Note that it's possible to use a union type in a constraint.
Upvotes: 5