首页 > 解决方案 > 字符串类型,将导入返回种类的模块

问题描述

我想定义一个 trypescript 函数,它接受一个字符串并返回一个对象。import该字符串是要使用动态或导入的模块的路径require。我希望参数类型比 更具体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 String literal expected。

标签: typescript

解决方案


如果您的路径是预先知道的(即在定义您的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'

推荐阅读