简体   繁体   English

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

[英]TypeScript - How to infer type information from constructor input parameters?

Say I have说我有

class Foo {}
class Bar {}

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

  result() {
    // snip
  }
}

Is it possible in typescript to say that given:是否可以在打字稿中说给定:

const query = new Query(Foo, Bar);

that query.result() will have return type [Foo, Bar] ? query.result()将有返回类型[Foo, Bar]

You could use Generics for that:你可以使用泛型:

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

For my specific use case (transforming variables within an Array) I ended up having to use a more sophisticated approach, using the techniques described here: https://medium.com/free-code-camp/typescript-curry-ramda-types-f747e99744ab对于我的特定用例(在数组中转换变量),我最终不得不使用更复杂的方法,使用此处描述的技术: https : //medium.com/free-code-camp/typescript-curry-ramda-types -f747e99744ab

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

InstanceTypes correctly converts [typeof A, typeof B, ...] to [A, B, C] as I require. InstanceTypes 按照我的要求正确地将 [typeof A, typeof B, ...] 转换为 [A, B, C]。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM