typescript - 有没有办法让打字稿推断数组的每个单独索引的类型,而函数中没有类型参数?
问题描述
标题可能令人困惑,我不确定如何正确表达它,但简而言之,我想完成以下任务:
type A<T extends new (...args: any) => any = any> = [T, Required<InstanceType<T>>];
function b<T extends new (...args: any) => any, T2 extends new (...args: any) => any>(...args: [A<T>, A<T2>?]) { };
class C { d?: string; e?: number };
class F { g?: string; h?: number };
b([C, { d: '', e: 2 }], [F, { g: '', h: 3 }]);
但是不必T, T2
在函数中包含类型参数b
,因为在我的用例中,函数不会为参数定义长度。这可能吗?如果没有,有更好的解决方案吗?
解决方案
假设您希望b
获取任意数量的 type 参数A
,这本身就是参数,那么不幸的是没有。这样做可能有一种 hacky 方式,但它肯定不干净,并且可能依赖递归类型来处理强制数组的第二个成员基于第一个成员进行类型检查。
核心问题是 Typescript 不支持更高种类的类型。所以你需要的是可以参数化的东西Array<T>
where T
is parameterized over A<K>
。这意味着需要一个b
看起来像这样的函数
export declare function b<T extends A<K>[]>(...args: T);
whereb
是参数化的,T
哪个是参数化的K
。这是目前在 TypeScript 中无法实现的。
您可以省略参数化K
并拥有
export declare function b<T extends A[]>(...args: T);
但是使用上面的 TypeScript 将无法强制执行数组的类型。例如,它将允许b([C, { doesnt_exist: '', e: true }]);
您缺少d
类中所需的属性C
并且e
类型错误。
为了在 TypeScript 中正确执行此操作,您需要将此函数的实现拆分为两个不同的函数,每个函数只能对一个类型参数进行参数化。
type A<T extends new (...args: any) => any = any> = [T, Required<InstanceType<T>>];
function makeA<T extends new (...args: any) => any>(a: A<T>) {return a;}
function b<T extends A[]>(...args: T) { };
class C { d?: string; e?: number };
class F { g?: string; h?: number };
class I { j?: string; k?: number };
b(makeA([C, { d: 'hello', e: 4 }]), makeA([F, { g: 'string', h: 5 }]), makeA([I, { j: 'test', k: 6 }]));
所以 nowb
是参数 onArray<T>
并且makeA
是参数 on A<K>
。因此,将这两者结合起来,您基本上得到了您正在寻找的更高种类的类型,尽管它不像在 Haskell 中那样实用。
以这种方式使用该b
函数更难,但您将在b
.
推荐阅读
- html - 窗口调整大小时元素重叠/消失
- c# - 如何绑定事件以从 MvvmCross 中的 ViewModel 查看?
- eclipse - 项目已经语法导入Eclipse后,如何进行附加操作?
- ruby-on-rails - 创建记录时,从关联记录中复制属性
- javascript - 为什么 onmouseenter(this) 事件返回的对象的子对象在以某种方式使用时会变为 null?
- django - 如何在跟踪以前的项目的同时从 Django 的列表中返回一个新的非重复项目?
- azure-devops - 使用私有访问令牌时 Azure DevOps 和 Git 授权不起作用
- python - 如何在 Python 中修复字符串索引超出范围异常
- bash - 如何在使用tail、while、read和的shell脚本中检测非滚动日志文件和模式匹配?
- ada - How do I turn off text overwriting when using gnatmake/GPS for ada?