如何约束打字稿泛型成为索引器?

Mot*_*tti 5 generics typescript

在打字稿,你可以索引到一个对象只使用stringnumbersymbol

我想有一个泛型,允许将泛型参数用作索引。

function foo<T extends number|string>(a: T): void {
    let x: any = {};
    x[a] = 42; // Error: an index expression argument must be of type...
}
Run Code Online (Sandbox Code Playgroud)

如果我强制转换为number|string,它将编译为:

function foo<T extends number|string>(a: T): void {
    let x: any = {};
    let i: number|string = a;
    x[i] = 42; // OK
}
Run Code Online (Sandbox Code Playgroud)

因此,类型检查器足够聪明,可以知道如果可以T扩展,number|string则可以将其分配给一个number|string(然后可以用来将其索引到一个对象中),但是由于某种原因,它不允许我T直接使用a进行索引。

有没有一种方法可以在通用约束中指定所传递的类型可以用作索引器?

注意:我使用的是泛型而不是number|string直接使用,因为我想将泛型限制为仅接受来自特定字符串enum字符串常量联合的值

编辑:一个更引人注目的示例(并且更接近我真正想做的事情)是:

// The following line fails to compile even though Key is number | string
type Dictionary<Key extends number | string, Value> = { [index: Key]: Value }; 

// Had it compiled I would expect the following behaviour
type Answer = "yes" | "no" | "maybe";
let grades = {} as Dictionary<Answer, number>;  

grades["yes"] = 10;
grades["nope"] = 5; // Should be an error "nope" is not assignable to Answer
Run Code Online (Sandbox Code Playgroud)

Mir*_*dze 6

// The following line fails to compile even though Key is number | string
type Dictionary<Key extends number | string, Value> = { [index: Key]: Value };
Run Code Online (Sandbox Code Playgroud)

使用in关键字:

type Dictionary<TKey extends number | string, TValue> = {
  [key in TKey]: TValue
};
Run Code Online (Sandbox Code Playgroud)