TypeScript 函数返回函数集

TypeScript Function returning set of Functions

我正在尝试将以下 vanilla JS 代码移植到 TypeScript 以更好地为所有函数定义 return 类型。此代码导出单个函数 resource。调用时,resource return 是一个包含其他函数的对象。

使用 Demo class 中的资源时,类型签名似乎消失了,在构造函数中进行了初始化。一种方法是为 resource 定义一个接口。但是,如果不重复 已经在 doThingOne()doThingTwo() 中定义的参数,我似乎无法为 resource 定义接口。我目前的尝试都导致我不得不复制签名。我应该如何处理这个问题以保持干燥?

function resource(someVar) {

    function doThingOne(p1 = '') {
        return Promise.resolve('thing one ' + someVar + p1);
    }

    function doThingTwo(p1 = '') {
        return Promise.resolve('thing two ' + someVar + p1);
    }

    return {
        doThingOne,
        doThingTwo
    };
}

class Demo {
    resource1;

    constructor() {
        this.resource1 = resource('resource1');
    }
}

const issues = new Demo();
issues.resource1 // no type information for resource1

一旦有 class 实例可以保存状态(在 resource 函数的情况下为 someVar),就不需要工厂函数了:

class Resource {
    constructor(private someVar: string);

    doThingOne(p1 = '') {
        return Promise.resolve('thing one ' + this.someVar + p1);
    }

    doThingTwo(p1 = '') {
        return Promise.resolve('thing two ' + this.someVar + p1);
    }
}

class Demo {
    resource1 = new Resource('resource1');
}

如果 Demo 不应该做任何其他事情,它们可以重构为单个 class。

您基本上希望将成员键入为函数的结果类型。

最简单的方法是让编译器根据赋值推断它:

class Demo {
    constructor(name: string, public resource1 = resource(name)) {

    }
}

const issues = new Demo("resource1");
issues.resource1 // correct type

如果这不切实际,您可以通过以下两种方式之一获取 return 类型:

在打字稿 2.8 中

使用ReturnType<T>条件类型。 (2.8 在撰写本文时尚未发布,但将于 2018 年 3 月发布,您可以通过 npm install -g typescript@next 获取)

class Demo {
    public resource1: ReturnType<typeof resource>
    constructor() {

    }
}

2.8 之前

您可以使用辅助函数和虚拟变量从函数中提取类型:

// Dummy function, just used to extract the result type of the function passed as the argument
function typeHelper<T>(fn: (...p:any[]) => T): T{
    return null as T;
}
// Dummy variable, null at runtime, but it's type is inferred as the result of the `resource function
let dummy = typeHelper(resource);

// Create a type definition based on the type of dummy
type resourceReturnType = typeof dummy;


class Demo {
    public resource1: resourceReturnType
    constructor() {

    }
}