错误报告
检索词: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 M
是string
。
// 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]: ... }
。
2条答案
按热度按时间eqqqjvef1#
关于第二个错误,
4
只是编写JavaScript键"4"
的另一种方式,因此该行为是故意的。另一个行为看起来像是bug
e1xvtsh32#
嗯。但是我发现如果我加上[key:number]:never,那么编译器会阻止我像那样使用数字作为键。如果字符串和数字是可以互换的,那为什么还能起作用呢?