Willwsharp
Willwsharp

Reputation: 723

Clarification on index type query operator and extends keyword

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

Answers (1)

David Sherret
David Sherret

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

Related Questions