[TypeScript] index type & lookup type

1. string literal type

string literal types 可以用来指定一个string type值的范围。例如,

type Easing = "ease-in" | "ease-out" | "ease-in-out";

Easing类型是string literal type,它是string的子类型。
Easing类型的string,只能取值为,"ease-in","ease-out","ease-in-out"。

string literal type也可以用于函数重载,

function createElement(tagName: "img"): HTMLImageElement;
function createElement(tagName: "input"): HTMLInputElement;

// ... more overloads ...
function createElement(tagName: string): Element {
    // ... code goes here ...
}

2. index type

TypeScript 2.1提供了index typelookup type

使用关键字keyof
可以得到一个类型T,所有属性名所构成的string literal union type,
称为index type。例如,

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

type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[];  // "length" | "push" | "pop" | "concat" | ...
type K3 = keyof { [x: string]: Person };  // string

3. lookup type

与index type相对应的是,lookup type(也称为indexed access types)。
在语法上,看起来像是获取属性的操作。
例如,

type P1 = Person["name"];  // string
type P2 = Person["name" | "age"];  // string | number
type P3 = string["charAt"];  // (pos: number) => string
type P4 = string[]["push"];  // (...items: string[]) => number
type P5 = string[][0];  // string

4. 应用

使用index type和lookup type,我们可以为类似下面的函数指定类型,

function pluck(o, names) {
    return names.map(n => o[n]);
}
function pluck(o: T, names: K[]): T[K][] {
  return names.map(n => o[n]);
}

interface Person {
    name: string;
    age: number;
}
let person: Person = {
    name: 'Jarid',
    age: 35
};
let strings: string[] = pluck(person, ['name']); // ok, string[]

其中,
(1)keyof T是index type,
(2)K[]T[K][]是lookup type,
(3)T extends U,是指TU的子类型,或者说,
T类型的值,可以安全的赋值给UT is assignable to U)。


参考

TypeScript 2.1
index types

你可能感兴趣的:([TypeScript] index type & lookup type)