【发布时间】:2020-03-25 05:18:50
【问题描述】:
考虑以下代码:
interface StringDoers {
[key: string]: (s: string) => void;
}
class MyStringDoers implements StringDoers {
public static print(s: string) {
console.log(s);
}
public static printTwice(s: string) {
console.log(s);
console.log(s);
}
}
这给了我一个类型错误:
“MyStringDoers”类错误地实现了“StringDoers”接口。
“MyStringDoers”类型中缺少索引签名
但从 Javascript 的角度来看,它确实实现了StringDoers。在 Javascript 控制台中,我可以完美地做到这一点:
class MyStringDoers {
static print(s) {
console.log(s);
}
static printTwice(s) {
console.log(s);
console.log(s);
}
}
MyStringDoers["printTwice"]("hello");
我想知道是不是因为[string]也可以返回undefined,例如
MyStringDoers["foo"]; // undefined
但是,即使将界面更改为此也不起作用:
interface StringDoers {
[key: string]: ((s: string) => void) | undefined;
}
我怎样才能做到这一点?限制是StringDoers 在第三方库中,所以我无法更改它。而且我想要一个了解所有方法的实际类型 - 即不仅仅是:
const doers: StringDoers = {
print(s: string) {
console.log(s);
},
...
}
我希望不知道答案的人会通过询问我为什么要这样做来尝试让自己感觉更好,所以:我的用例是为 Vuex 的 MutationTree 添加正确的类型。
【问题讨论】:
-
类似但没有。我的问题是为什么静态函数不实现索引。不是如何实现索引本身。
-
它确实实现了 StringDoers - 不,它没有。静态属性与实现接口无关
-
@Timmmm 不过,我仍然认为这是该问题的重复。您接受的答案具有误导性。虽然在技术上没有错误,但它只是规避了错误消息。事实上,这比根本不实现接口还要糟糕。您可以将任何静态方法添加到您的类中,例如
public static meth(n: number): string { /* */ },并且仍然有一个有效的类而没有任何编译器警告。在这种情况下,实现接口不会给它增加任何意义。真正的答案在我链接到的问题中:你不能以你想要的方式在类中实现可索引类型。 -
Implement an indexible interface 的可能重复项。
-
是的,它绕过了错误消息,但不是唯一的选择,因为 Typescript 不够聪明,无法知道函数 由
[key: string]访问。MyStringDoers['foo']和map['foo']有什么区别?据我所知,没有任何类型。
标签: typescript