简体   繁体   English

从泛型的返回类型推断参数

[英]Infer parameters from return type of generic

I'm creating a function whereby the first parameter is an array of "services", and the second parameter infers the return type of those services.我正在创建一个 function,其中第一个参数是“服务”数组,第二个参数推断这些服务的返回类型。 For example:例如:

const serviceOne = createService([], () => Promise.resolve({} as Service1));
const serviceTwo = createService([], () => Promise.resolve({} as Service2));

const serviceThree = createService(
  [serviceOne, serviceTwo],
  (one, two) => Promise.resolve({}), // one should be inferred as Service1, two should be inferred as Service2
);

How can I modify my function signature to achieve this inference?如何修改我的 function 签名来实现这个推断? At the moment, I have them typed as any目前,我将它们按any类型输入

function createService<T extends Service<any>[], U>(deps: T, factory: (...args: any[]) => Promise<U>) {
  return {} as Service<U>;
}

type Service<U> = {
  instance: U
};

Playground 操场

You can first need to change the constraint to T to get typescript to infer a tuple type instead of an array type.您可能首先需要将约束更改为T以获得 typescript 以推断元组类型而不是数组类型。 To do this, we just need to add a union with the empty tuple to the constraint ( [] | ).为此,我们只需要将带有空元组的联合添加到约束 ( [] | )。 This will set typescript in the right state to infer tuples这将在右侧 state 中设置 typescript 以推断元组

We can then use a mapped type to map from a tuple containing Service<any> to a tuple containing the service types:然后我们可以使用映射类型到 map,从包含Service<any>的元组到包含服务类型的元组:

const serviceThree = createService(
  [serviceOne, serviceTwo],
  (one, two) => Promise.resolve({} as Service3), // one is Service1, two is Service2
);

type GetServiceType<T extends Service<any>[]> = unknown [] & {
  [P in keyof T]: T[P] extends Service<infer R> ? R: never
}
function createService<T extends [] | Service<any>[], U>(deps: T, factory: (...args: any[] & GetServiceType<T>) => Promise<U>) {
  return {} as Service<U>;
}

Playground Link 游乐场链接

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

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