是的,它有一定的灵活性,但不太灵活-您可以使用从数据推断出的方法名的类型,但数据必须以字符串文本的形式出现-您不能使用包含方法所需名称的变量,请将该变量传递给
module
函数并神奇地获取具有该名称的类型。
我不确定这是否值得:
declare function module<I, U extends string = string, A extends string = string, R extends string = string>(
instance: I,
options: module.Options<U, A, R>
): module.Module<I, U, A, R>
declare namespace module {
interface DefaultModule<I> {
use(): any;
after(): any;
ready(): any;
}
type Module<I, U extends string, A extends string, R extends string> =
string extends U ? DefaultModule<I> :
string extends A ? DefaultModule<I> :
string extends R ? DefaultModule<I> :
// here we have specific names in U, A, R, not just strings
{ [u in U]: () => any } & { [a in A]: () => any } & { [r in U]: () => any }
;
interface Options<U extends string = string, A extends string = string, R extends string = string> {
expose?: {
use?: U;
after?: A;
ready?: R;
}
}
}
interface ExposeNames<U extends string, A extends string, R extends string> {
useName: U;
afterName: A;
readyName: R;
}
function moduleOptions<U extends string, A extends string, R extends string>({useName, afterName, readyName}: ExposeNames<U, A, R>): module.Options<U, A, R> {
return {
expose: {use: useName, after: afterName, ready: readyName}
}
}
const moduleA = module({}, {});
moduleA.use();
const moduleB = module({}, moduleOptions({ useName: 'use1', afterName: 'after1', readyName: 'ready1' }));
moduleB.use1();