在我的应用程序中,我有几个用于创建XML字符串的类。 每个类都有一些带有一些参数并返回字符串的方法。我想指定此限制,以便不能添加具有不同签名或其他类成员的方法。为此,这是我到目前为止的去处:
interface IRequestParser {
[funcName: string]: (...args: any[]) => string;
}
和一个类的示例:
class myParser implements IRequestParser {
[funcName: string]: (...args: any[]) => string;
func1(a) {
return '';
}
}
这使我无法添加不返回字符串或任何其他非方法成员的函数,因此在myParser
内不允许使用这些函数:
a: string; // not allowed
b() { // not allowed
return 5;
}
但是,这样做的效果是让我在没有警报的情况下从myParser
实例调用任何函数名称:
const a = new myParser();
console.log(a.func1('a'));
console.log(a.func2(4, 5, ['s', 'b']));
对func1
的调用是有道理的,如果不为其参数a
提供值,我也会得到一个错误。但是,我也可以调用不存在的函数func2
和任何其他名称。
是否有办法既限制类成员的类型,又避免这种以任何名称调用任何函数的情况?
答案 0 :(得分:3)
您使用的接口允许用任何字符串索引该类。我们无法通过界面来表达您想要的约束(至少我无法想到,也许其他人有想法)。
您可以使用函数将类限制为仅具有带有签名的函数,同时保留类具有的实际属性:
type ParserFn = (...args: any[]) => string;
function createRequestParserClass<
T extends new (...a: any[]) => Record<keyof InstanceType<T>, ParserFn>>(ctor: T) {
return ctor
}
const myParser = createRequestParserClass(class {
// a: string; // not allowed
// b() { // not allowed
// return 5;
// }
func1(a: string) {
return '';
}
});
type myParser = InstanceType
const a = new myParser();
console.log(a.func1('a'));
console.log(a.func2(4, 5, ['s', 'b'])); // error now
console.log(a.func1(1)); // also error
答案 1 :(得分:3)
您也可以这样做:
class MyParser implements Record<keyof MyParser, (...args: any[]) => string> {
// okay
func1(a: any) {
return '';
}
// error: string is not assignable to (...args: any[]) => string
a: string;
// error: number is not assignable to string
b() {
return 5;
}
}
const myParser = new MyParser();
myParser.func1("okay"); // works
myParser.funcNope("huh"); // error, no property funcNope
允许实现一个具体的映射类型(例如Record<>
),有时也可以使用循环引用(通常可以接受通过keyof
来引用键)。
希望有所帮助;祝你好运!