The next best thing might be to allow ArrayOfMyRecords to itself be a generic type in which each element of the array is strongly typed with its analogous T value, and a helper function to infer the stronger type:type MyRecord<T> = [T, (arg: T) => void];const asMyRecordArray = <A extends any[]>( a: { [I in keyof A]: MyRecord<A[I]> } | []) => a as { [I in keyof A]: MyRecord<A[I]> };这使用映射类型的推断和映射的元组.让我们看看它的作用:This uses infererence from mapped types and mapped tuples. Let's see it in action:const arr = asMyRecordArray([ [str, acceptString], [num, acceptNumber], [str, acceptNumber] // error]);// inferred type of arr:// const arr: [// [string, (arg: string) => void],// [number, (arg: number) => void],// [string, (arg: string) => void]// ]让我们解决这个问题:const arr = asMyRecordArray([ [str, acceptString], [num, acceptNumber], [str, acceptString]]);// inferred type of arr:// const arr: [// [string, (arg: string) => void],// [number, (arg: number) => void],// [string, (arg: string) => void]// ]因此足以定义arr.但是,现在看看当您对其进行迭代时会发生什么:So that works well enough to define arr. But now look what happens when you iterate over it:// TS3.3+ behaviorfor (const pair of arr) { const [arg, func] = pair; func(arg); // still error!}这是缺少相关记录支持的地方,这会伤到您.在TypeScript 3.3中,添加了对调用函数类型的联合的支持,但是该支持确实可以不能解决这个问题,即:编译器将func视为函数的 union ,这些函数与>类型完全 unorrelated 完全无关.当您调用它时,编译器决定它只能安全地接受类型为string & number的参数,而arg不是(也不是任何实际值,因为string & number折叠为never).This is where the lack of support for correlated records burns you. In TypeScript 3.3, support was added for calling unions of function types, but that support does not touch this issue, which is: the compiler treats func as a union of functions which is completely uncorrelated with the type of arg. When you call it, the compiler decides that it can only safely accept arguments of type string & number, which arg is not (nor is any actual value, since string & number collapses to never).因此,如果您采用这种方式,将会发现您需要类型断言,以使编译器平静下来:So if you go this way you'll find you need a type assertion to calm the compiler down:for (const pair of arr) { const [arg, func] = pair as MyRecord<string | number>; func(arg); // no error now func(12345); // no error here either, so not safe}一个人可能会认为这是您可以做的最好的事情,然后把它留在那里.One might decide this is the best you can do and to leave it there.现在,有一种方法可以在TypeScript中编码存在类型,但是它涉及类似于Promise的控件反转.不过,在走那条路线之前,请问问自己:当您不知道T时,您将如何实际使用MyRecord<T> ?您可以做的唯一合理的事情是将其第一个元素称为第二个元素.如果是这样,您可以给出一种更具体的方法,只需做到这一点而无需跟踪T:Now, there is a way to encode existential types in TypeScript, but it involves a Promise-like inversion of control. Before we go down that route, though, ask yourself: what are you going to actually do with a MyRecord<T> when you don't know T ? The only reasonable thing you can do is to call its first element with its second element. And if so, you can give a more concrete method that just does that without keeping track of T:type MyRecord<T> = [T, (arg: T) => void];type MyUsefulRecord<T> = MyRecord<T> & { callFuncWithArg(): void };function makeUseful<T>(arg: MyRecord<T>): MyUsefulRecord<T> { return Object.assign(arg, { callFuncWithArg: () => arg[1](arg[0]) });}const asMyUsefulRecordArray = <A extends any[]>( a: { [I in keyof A]: MyUsefulRecord<A[I]> } | []) => a as { [I in keyof A]: MyUsefulRecord<A[I]> };const arr = asMyUsefulRecordArray([ makeUseful([str, acceptString]), makeUseful([num, acceptNumber]), makeUseful([str, acceptString])]);for (const pair of arr) { pair.callFuncWithArg(); // okay!}您的真实示例可以进行类似的修改:Your real-world example could be modified similarly:function creatify<T, U>(arg: [new () => T, new (x: T) => U]) { return Object.assign(arg, { create: () => new arg[1](new arg[0]()) });}const map = { [Type.Value1]: creatify([Store1, Form1]), [Type.Value2]: creatify([Store2, Form2])};function createForm(type: Type) { return map[type].create();}在TypeScript中模拟存在性类型与上述类似,不同之处在于它允许您对MyRecord<T>进行绝对任何操作,如果您不知道T则可以执行.由于在大多数情况下,这只是一小部分操作,所以直接直接支持这些操作通常会更容易.Emulating existential types in TypeScript is similar to the above except that it allows you to do absolutely anything to a MyRecord<T> that can be done if you don't know T. Since in most cases this is a small set of operations, it's often easier to just support those directly instead.好的,希望能有所帮助.祝你好运!Okay, hope that helps. Good luck! 这篇关于如何通过TypeScript中的类型描述元组数组中元组元素之间的关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 09-02 14:18