TypeScript-如何从构造函数输入参数推断类型信息?

TypeScript-如何从构造函数输入参数推断类型信息?,typescript,Typescript,说我有 class Foo {} class Bar {} class Query { construct(...args: any[]) { // snip } result() { // snip } } 在typescript中是否可以说: const query = new Query(Foo, Bar); query.result()将具有返回类型[Foo,Bar]?您可以使用泛型: class Foo{} class Bar{} class

说我有

class Foo {}
class Bar {}

class Query {
  construct(...args: any[]) {
    // snip
  }

  result() {
    // snip
  }
}
在typescript中是否可以说:

const query = new Query(Foo, Bar);

query.result()
将具有返回类型
[Foo,Bar]

您可以使用泛型:

class Foo{}
class Bar{}

class Query<T> {
    constructor(private arg: T) {
    }
    
    query (): T {
        return this.arg;
    }
}

const q = new Query<[Foo, Bar]>([new Foo(), new Bar()]);
const q.query() // typehints [Foo, Bar] as returntype
class Foo{}
类条{}
类查询{
构造函数(专用参数:T){
}
查询():T{
返回this.arg;
}
}
const q=新查询([new Foo(),new Bar()]);
const q.query()//类型提示[Foo,Bar]作为返回类型
对于我的特定用例(在数组中转换变量),我最终不得不使用更复杂的方法,使用这里描述的技术:

/*eslint disable@typescript eslint/无显式任何*/
类型长度=T['Length']
类型Cast=X扩展到Y?X:Y;
类型前置=
((head:E,…args:T)=>any)扩展((…args:inferu)=>any)
? U
:T
类型Pos=
长度;
键入下一个=
预弯;
类型反转<
T扩展任何[],
R扩展任何[]=[],
我扩展了任何[]=[]
> = {
0:反向
1:R
}[
Pos扩展长度
1.
: 0
]
海螺型=
反向;
类型附加=
海螺;
导出类型实例类型<
T扩展{new(…args:any):any}[],
R扩展任何[]=[],
我扩展了任何[]=[]
> = {
0:实例类型<
T
附加扩展推断U
铸造
:从不,
下一个
>
1:R
}[
Pos扩展长度
1.
: 0
];

InstanceTypes按照我的要求将[typeof A,typeof B,…]正确地转换为[A,B,C]。

query=query(Foo,Bar)
--这样使用时,
query
不是构造函数,而是常规函数。为了成为构造函数,必须使用
new
。从面向对象的角度来看,对象是一个智能组件,而不仅仅是一个哑容器。如果构造函数接受任何参数,那么您的“类”就不是一个类,这只是实现哑容器的一种复杂方式。@axiac打字错误已修复。我没有考虑过将其合并到一个泛型参数中。我认为它必须是查询,…args:T或类似的,因为我需要知道给定的arg[0]是Foo,响应[0]将是Foo的实例,等等。我将看看是否可以获得一些这方面的经验。谢谢你的意见!如果我的回答对你有帮助。如果你把它标为接受,我会很高兴的
/* eslint-disable @typescript-eslint/no-explicit-any */
type Length<T extends any[]> = T['length']

type Cast<X, Y> = X extends Y ? X : Y;

type Prepend<E, T extends any[]> =
  ((head: E, ...args: T) => any) extends ((...args: infer U) => any)
    ? U
    : T

type Pos<I extends any[]> =
  Length<I>;

type Next<I extends any[]> =
  Prepend<any, I>;

type Reverse<
  T extends any[],
  R extends any[] = [],
  I extends any[] = []
> = {
  0: Reverse<T, Prepend<T[Pos<I>], R>, Next<I>>
  1: R
}[
  Pos<I> extends Length<T>
    ? 1
    : 0
]

type Concat<T1 extends any[], T2 extends any[]> =
  Reverse<Reverse<T1> extends infer R ? Cast<R, any[]> : never, T2>;

type Append<E, T extends any[]> =
  Concat<T, [E]>;

export type InstanceTypes<
  T extends { new(...args: any): any}[],
  R extends any[] = [],
  I extends any[] = []
> = {
  0: InstanceTypes<
    T,
    Append<InstanceType<T[Pos<I>]>, R> extends infer U
      ? Cast<U, any[]>
      : never,
    Next<I>
  >
  1: R
}[
  Pos<I> extends Length<T>
    ? 1
    : 0
];