如何在打字稿中使用通用返回值注释函数 [英] How to annotate a function with a generic return value in typescript

查看:88
本文介绍了如何在打字稿中使用通用返回值注释函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个返回工厂的函数,如何注释该函数/工厂,使其包含正确的类型定义?

Given a function that returns a factory, how can I annotate the function/factory so that it contains the correct type definitions?

这是我的例子:

class item<T> {
  constructor(a: T) {
    this.a = a;
  }
  a: T
}

function generate(c) {
  return function a(a) {
    return new c(a);
  }
}

const factory = generate(item); // I want this to always be annotated as <T> (a: T) => item<T>

const instance = factory('string'); // instance should now be of type item<string>

这可能是打字稿中的问题吗,还是应该将其作为一项新功能推荐?

Is this possible in typescript or should I suggest it as a new feature?

推荐答案

对于非通用类,我们可以在3.0中使用

For non generic classes we can in 3.0 use Tuples in rest parameters and spread expressions and InstanceType to map the constructor to a similar function.

不幸的是,对于泛型类,在映射时无法保留类型参数.唯一的解决方案是在类中添加一个字段,该字段将告诉generate结果类型应该是什么.可以使用接口类合并来完成此操作,因此原始类不了解generate.

For generic classes unfortunately there is no way to preserve the type argument when mapping. The only solution is to add a field to the class that will tell generate what the result type should be. This can be done using interface-class merging so the original class does not know about generate.

使用这两种方法的解决方案(在可能的情况下为自动,在必要的情况下为手动)可能看起来像这样:

A possible solution using both approaches (automatic where possible, manual where necessary) could look something like this:

class item<T> {
    constructor(a: T) {
        this.a = a;
    }
    a: T
}

const generateResult = Symbol.for("generate")
interface item<T> {
    [generateResult] : <T>(a: T) => item<T>    
}

type d = item<any>[typeof generateResult]

type SupportsGeneration<R> =  { [generateResult] : R }
type ConstructorArguments<T> = T extends new (...a:infer A ) => any ? A : [];


function generate<T extends { new (...a:any[]) : SupportsGeneration<any> }>(c:T) :  InstanceType<T> extends SupportsGeneration<infer R> ? R: never
function generate<T extends new (...a:any[]) => any>(c:T) :  (a: ConstructorArguments<T>) => InstanceType<T>
function generate(c: new (...a: any[]) => any) : any {
    return function a(...a: any[]) {
        return new c(...a);
    }
}

const factory = generate(item); 

const instance = factory('string');

这篇关于如何在打字稿中使用通用返回值注释函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆