TypeScript 无法约束泛型参数以具有字符串键?

a0x5cqrl  于 2022-10-29  发布在  TypeScript
关注(0)|答案(2)|浏览(195)

错误报告

检索词:Type 'X' cannot be used to index type 'Y',约束泛型参数以具有字符串键

  • 这是我尝试过的每个版本的行为

代码

Playground链接
此类型用于将另一个类型的值Map到{message: V}数组,但也允许将{message:unknown}用于其他字符串键。

type Example<M> =
  { [K in keyof M]?: {message: M[K]}[] } &
  { [key in string]: {message: unknown}[] };

例如,意图是Example<{ foo: string }>应变为

{
  foo: {message: string}[];
  [key: string]: {message: unknown}[];
}

这是可行的:我们知道“foo”和其他字符串是有效的键。

const obj: Example<{foo: string}> = {};
obj["foo"] = [{message: "hi"}];
obj["bar"] = [{message: "x"}];

但是,尝试使用带有泛型参数**的Example**会产生错误。即使我们不知道M[“foo”],我们也应该知道keyof Mstring

// attempt to constrain M's keys to be strings
function test<M extends {[key in string]: unknown}>() {
  const obj: Example<M> = {};
  obj["foo"] = [];  // error: Type '"foo"' cannot be used to index type 'Example<M>'.
  obj["bar"] = [];  // error: Type '"foo"' cannot be used to index type 'Example<M>'.
}
// should fail, but doesn't -- we've tried to constrain M to have string keys
test<{ 4: string }>();

🙁实际行为

M是泛型参数时,无法使用字串为Example<M>建立索引。

🙂预期行为

应该始终可以使用字符串进行索引,因为Example的定义包括{ [key in string]: ... }

eqqqjvef

eqqqjvef1#

关于第二个错误,4只是编写JavaScript键"4"的另一种方式,因此该行为是故意的。
另一个行为看起来像是bug

e1xvtsh3

e1xvtsh32#

嗯。但是我发现如果我加上[key:number]:never,那么编译器会阻止我像那样使用数字作为键。如果字符串和数字是可以互换的,那为什么还能起作用呢?

相关问题