字符串类型,它将导入返回一种类型的模块

时间:2019-08-02 22:33:29

标签: typescript

我想定义一个trypescript函数,该函数接受一个字符串并返回一个对象。字符串是使用动态importrequire导入模块的路径。我希望参数类型比string更具体,如果字符串不是所需类型的模块的路径,我希望它是类型错误。

factory('./path/to/string-fn'); // should error, () => string not compatible with () => number.
factory('./path/to/number-fn');  // should not error

async function factory(path: T): Promise<number> {
  const {default: fn} = await import(path);
  return fn()
}


# path/to/string-fn
export default function hello(): string {
  return 'hello';
}
# path/to/number-fn
export default function zero(): string {
  return 0;
}

type MODULE = typeof import('./path/to/number-fn')解析为模块的形状,但是type PATH = './path'; type MODULE = typeof import(PATH)产生错误1141预期的字符串文字。

2 个答案:

答案 0 :(得分:0)

您可以这样声明一个类:

export class Path {
  constructor(private path: string) {
    if (!someTestForValidPath(path)) {
      throw new Error('Bad path! Bad!');
    }
  }

  toString(): string {
    return this.path;
  }
}

然后将其用作工厂功能的参数。

答案 1 :(得分:0)

如果您的路径是事先已知的(即在定义factory函数时),则可以像下面这样键入函数:

type NumberFunctionPaths = "./path/to/number-fn" | "./path/to/other-number-fn";

async function factory(path: NumberFunctionPaths): Promise<number> {
  const {default: fn} = await import(path);
  return fn()
}

请注意,如果您从父目录或子目录中调用factory(),这也将起作用,因为该路径将相对于工厂函数本身保持相对(因为导入位于此处)。


或者,如果您可以将导入本身移动到调用方,则可以这样做:

interface NumberFuncModule {
    default: () => number;
}

async function factory(func: Promise<NumberFuncModule>): Promise<number> {
    const { default: fn } = await func;
    return fn();
}

factory(import("./number-fn"));
factory(import("./string-fn"));
     // ^^^^^^^^^^^^^^^^^^^^^ Type '() => string' is not assignable to type '() => number'