typescript - 从模块名称列表中推断函数参数类型
问题描述
我有很多旧.js
文件目前无法迁移到.ts
文件中。我正在添加.d.ts
文件以添加类型,但是使用类型是一个问题,因为文件通过 requireJs 相互导入,如下所示:
define(['moduleA', 'moduleB'], function(moduleA, moduleB) {
// ...
});
我希望在这种情况下正确键入函数参数moduleA
和。moduleB
由于模块名称 ( 'moduleA', 'moduleB'
) 是在运行时配置文件中自定义的,TypeScript 无法真正帮助连接这些点。
所以我有一个想法是增加 的类型define
,以便它需要来自第一个参数的模块名称列表,将它们映射到映射接口中定义的模块类型,然后将函数参数键入到第二个参数是模块类型列表。
我得到了基本的概念证明:
/**
* This interface is used to map module names to their types.
*/
export interface RequireJsModules {
foo: boolean;
bar: string;
}
export type RequireJsModulify<T extends string[]> = {
[P in keyof T]: T[P] extends keyof RequireJsModules
? RequireJsModules[T[P]]
: unknown
};
// This line is for testing `RequireJsModulify`.
type Foo = RequireJsModulify<['foo', 'bar', 'wut']>;
此屏幕截图显示RequireJsModulify
正在运行。Type ofFoo
是基于模块名称元组的正确模块类型的元组。
我坚持的是define
函数签名:
declare global {
export function define<T extends string[], U extends RequireJsModulify<T>>(
deps: T,
moduleFactory: ((...args: U) => any)
): void;
}
这个想法是,参数moduleFactory
必须是基于类型参数的映射模块类型,类型参数T
是字符串的任意列表。如果字符串是映射接口的键RequireJsModules
,则相应的函数参数应该具有该模块类型,否则参数应该具有类型unknown
。
我有这个测试用例:
describe('requirejs type', () => {
it('should call the module factory with the correct types corresponding to the dependencies', () => {
// There should be no type errors below.
define(['foo', 'bar', 'wut'], function(foo, bar, wut) {
const fooExpected: boolean = foo;
const barExpected: string = bar;
const wutExpected: unknown = wut;
console.log({ fooExpected, barExpected });
});
});
});
如果 for 的类型define
按我想要的方式工作,那么第一个参数foo
应该是 type boolean
,第二个参数bar
应该是 type string
,而第三个应该是unknown
。
但他们都unknown
在此刻。
因此:
我正在使用 TypeScript 3.9.7。
任何想法为什么它不起作用?
解决方案
推荐阅读
- java - JAVA:如何使特定用户的所有 JWT 令牌无效?
- html - R Kable add_header_above 在空白处添加行
- c - 如何格式化数组并使用户的输入符合数组格式
- python-3.x - 涉及 MulExpression 的 cvxpy 目标函数错误
- c++ - 以获取一致性与宽松一致性在原子负载上旋转
- android - 在 webview 中添加输入后,PopScope 将不起作用吗?
- javascript - 将外部 HTML 加载到页面中,包括 Javascript 并在加载时启动 JS
- python - 生成器函数不返回或打印任何内容
- jquery - Rails,如何在特定页面上显示 jquery-ui-datepicker 日历?
- r - UseMethod(“filter_”)中的错误:没有适用于“filter_”的方法应用于“c('double','numeric')”类的对象