Skip to content

Latest commit

 

History

History
190 lines (140 loc) · 3.76 KB

Index-types.md

File metadata and controls

190 lines (140 loc) · 3.76 KB
tree_title description last_modified
Index types
Some examples of TypeScript index types and how to use them
2020-11-21 18:14:37 UTC

Index types (TypeScript)

Contents

Index operators

Index type query operator: keyof

interface Test {
    propA: number;
    propB: string;
}

type TestKey = keyof Test; 
// type TestKey = "propA" | "propB"

Indexed access operator: T[K]

Can be used in generic context to indicate property types

Example (adapted from Index types):

interface Test {
    propA: number;
    propB: string;
}

function getProperty<T, K extends keyof T>(o: T, propertyName: K): T[K] {
    return o[propertyName]; // o[propertyName] is of type T[K]
}

const test: Test = { propA: 1, propB: "b" };

getProperty(test, "propA"); // type number
getProperty(test, "propB"); // type string

Index signatures

Can be used to specify structure of object with arbitrary property names

interface IndexSignature {
    [key: string]: boolean | number;
    a: boolean;
    b: number;
}

function test(input: IndexSignature) {
    input.a // type boolean
    input.b // type number
    input.c // type boolean | number;
}

Can also be used with generics:

interface GenericIndexSignature<T> {
    [key: string]: T;
}

function test(input: GenericIndexSignature<number>) {
    input.c // type number;
    input.d // type number;
}

Use case: mapped types

Mapped types = new types based on other types

Readonly and Partial

Implementations (already provided by TypeScript language):

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Partial<T> = {
  [P in keyof T]?: T[P];
};

Example:

interface Person {
    name: string;
    age: number;
}

type ReadonlyPerson = Readonly<Person>;
// type ReadonlyPerson = { readonly name: string; readonly age: number; }

type PartialPerson = Partial<Person>;
// type PartialPerson = { name?: string | undefined; age? : number | undefined; }

Pick

Implementation (already provided by TypeScript language):

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

Example:

interface Test {
    propA: string;
    propB: number;
    propC: boolean;
}

type Picked = Pick<Test, "propA" | "propC">;
// type Picked = { propA: string; propC: boolean; }

Use case: dictionaries with enum or type union keys

Example with enum keys:

enum TestEnum {
  First = "First",
  Second = "Second",
  Third = "Third"
}

type DictionaryWithAllKeys = { [key in TestEnum]: number; };
type DictionaryWithSomeKeys = { [key in TestEnum]?: number; };

// error: property 'Third' is missing
const testAllKeys: DictionaryWithAllKeys = {
  First: 1,
  Second: 2
}

const testSomeKeys: DictionaryWithSomeKeys = {
  First: 1,
  Second: 2
}

Example with type union keys:

type TestUnion = "First" | "Second" | "Third";

type DictionaryWithAllKeys = { [key in TestUnion]: number; };
type DictionaryWithSomeKeys = { [key in TestUnion]?: number; };

// error: property 'Third' is missing
const testAllKeys: DictionaryWithAllKeys = {
  First: 1,
  Second: 2
}

const testSomeKeys: DictionaryWithSomeKeys = {
  First: 1,
  Second: 2
}

Resources