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
];