考虑以下打字稿example:
interface XInput { xin: number; }
interface XOutput { xout: number; }
interface YInput { yin: number; }
interface YOutput { yout: number; }
interface FMap {
getX: any;
getY: any;
}
interface InputMap extends FMap {
getX: XInput;
getY: YInput;
}
interface OutputMap extends FMap {
getX: XOutput;
getY: YOutput;
}
class MethodDictionary<FM, MI extends FM, MO extends FM> {
private _methods: any = {};
define<N extends keyof FM>(name: N, fn: (a: MI[N]) => MO[N]) {
this._methods[name] = fn;
}
call<N extends keyof FM>(name: N, input: MI[N]) {
this._methods[name](input);
}
}
const mapper = new MethodDictionary<FMap, InputMap, OutputMap>();
mapper.define('getX', (a: XInput): XOutput => { return { xout: 0 }; });
mapper.call('getX', { xin: 0 });
在这个例子中,我希望定义一个函数映射器,它接受函数的名称并强制我们定义接受某些输入并给出一些输出的函数。在这种情况下,我想强迫自己写 以下功能:
interface MyMethods {
getX: (a: XInput) => XOutput;
getY: (a: YInput) => YOutput;
}
我本可以写下以下内容:
class OtherMapper<M> {
private _methods: any = {};
define<N extends keyof M>(name: N, fn: M[N]) {
this._methods[name] = fn;
}
}
我会达到与上述相同的效果。也就是说,如果我们写:
mapper.define('otherKey', ...)
打字稿会告诉我们只允许getX | getY
。如果我们要更改功能的输入或输出,它也会警告我们。
但我无法编写call
方法的定义。你们有没有看到我们可以简化工作示例的方式,这样打字稿仍然可以告诉我们我们使用的类型,还有办法定义一个更简单的合同?也就是说,我们可以定义
interface MethodMap {
getX: [XInput, XOutput];
getY: [YInput, YOutput];
}
并将其用作我们映射器的唯一通用参数?我想写这个,但它不起作用:
class MethodDictionary<M> {
private _methods: any = {};
define<N extends keyof M>(name: N, fn: (a: M[N][0]) => M[N][1]) {
this._methods[name] = fn;
}
call<N extends keyof M>(name: N, input: M[N][0]) {
this._methods[name](input);
}
}
答案 0 :(得分:0)
$autoload['libraries'] = array('database', 'session', 'datatables');