1

我目前面临以下情况:

我写了一个 JS 模块的 typescript 定义,这个模块的调用函数是这样的:

declare function module<I>(
  instance: I,
  options: module.Options
): module.Module<I>

和模块命名空间:

declare namespace module {
  interface Module<I> {
    use(): any;
    after(): any;
    ready(): any;
  }

  interface Options {
    expose?: {
      use?: string;
      after?: string;
      ready?: string;
    }
  }
}

暴露选项用于更改module.module中的方法名称,只是,我不知道:

1) 就像在使用、之后和就绪名称时有一个默认后备

2)让用户为这些方法指定一个新名称

我不知道 Typescript 是否有这种灵活性^^

4

1 回答 1

1

是的,它有一定的灵活性,但并不多——你可以有一个从数据中推断出方法名称的类型,但数据必须以字符串文字的形式出现——你不能有一个包含方法所需名称的变量,通过该变量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();
于 2018-06-12T16:49:35.463 回答