Indexed Types

There are times when you find yourself duplicating types. A common example is nested resources in an auto-generated API response.

interface ArtworkSearchResponse {
  artists: {
    name: string;
    artworks: {
      name: string;
      deathdate: string | null;
      bio: string;
    }[];
  }[];
}

// If this interface were hand-crafted, it's pretty easy to imagine pulling out the artworks into an interface like:
interface Artwork {
  name: string;
  deathdate: string | null;
  bio: string;
}

// However, in this case we don't control the API, and if we hand-created the interface then it's possible that the artworks part of ArtworkSearchResponse and Artwork could get out of sync when the response changes. The fix for this is indexed types, which replicate how JavaScript allows accessing properties via strings.
type InferredArtwork = ArtworkSearchResponse["artists"][0]["artworks"][0];

// The InferredArtwork is generated by looking through the type's properties and giving a new name to the subset which you have indexed.