Index signature - pnlinh-it/hello-typescript GitHub Wiki

Using the Indexed Access Operator

  • Essential of Typescript
import { City, Person, Product, Employee } from "./dataTypes";

function getValue<T, K extends keyof T>(
    item: T, keyname: K) { console.log(`Value: ${item[keyname]}`);
}
type priceType = Product["price"];
type allTypes = Product[keyof Product];

let p = new Product("Running Shoes", 100); 
getValue<Product, "name">(p, "name"); getValue(p, "price");

let e = new Employee("Bob Smith", "Sales"); 
getValue(e, "name");
getValue(e, "role");

The indexed access operator is expressed using square brackets following a type so that Product["price"], for example, is number, since that is the type of the price property defined by the Product class. The indexed access operator works on literal value types, which means it can be used with index type queries, like this:

type allTypes = Product[keyof Product]; 

The keyof Product expression returns a literal value type union with the property names defined by the Product class, "name" | "price". The indexed access operator returns the union of the types of those properties, such that Product[keyof Product] is string | number, which is the union of the types of the name and price properties.

The indexed access operator is most commonly used with generic types, which allows property types to be handled safely even though the specific types that will be used are unknown,

import { City, Person, Product, Employee } from "./dataTypes";
function getValue<T, K extends keyof T>(item: T, keyname: K): T[K] {
    return item[keyname];
}
let p = new Product("Running Shoes", 100);
console.log(getValue<Product, "name">(p, "name")); 
console.log(getValue(p, "price"));

let e = new Employee("Bob Smith", "Sales");
console.log(getValue(e, "name")); 
console.log(getValue(e, "role"));

image

T[K] tells the compiler that the result of the getValue function will have the type of the property whose name is specified by the keyof type argument, leaving the compiler to determine the result types based on the generic type arguments used to invoke the function. For the Product object, that means a name argument will produce a string result, and a price argument will produce a number result.

class Collection<T, K extends keyof T> implements Iterable<T> {
  private items: Map<T[K], T>;

  constructor(initialItems: T[] = [], private propertyName: K) {
    this.items = new Map<T[K], T>();
    this.add(...initialItems);
  }

  get(key: T[K]): T {
    return this.items.get(key);
  }
}
⚠️ **GitHub.com Fallback** ⚠️