在 TypeScript 中将类型作为变量返回

jmi*_*del 3 javascript types factory object typescript

我目前正在用 TypeScript 编写一个类工厂,并希望返回一个类型作为函数的输出。尽管 TypeScript 将类型作为输入处理——即泛型——很漂亮,但我还没有找到一种将类型作为输出处理的方法。

这个关于类工厂的 StackOverflow 问题提供了一个特别有用的解决方案,但没有完全回答我的问题。鉴于以下结构,

function factory(someVar: any) {
    return class A {
        // Do something with someVar that makes this class unique
    }
}
Run Code Online (Sandbox Code Playgroud)

该问题表明,应该使用此工厂函数的输出执行以下操作:

import factory from "someLocation";

const AClass = factory({foo: "bar"});
type A = InstanceType<typeof AClass>;

interface IData {
    someField: A;
}
Run Code Online (Sandbox Code Playgroud)

我有兴趣在我的工厂函数中包含此功能,以使系统更具可重用性或模块化。但是,正如最初所述,我不确定如何从函数返回类型。如果我尝试以下操作,TypeScript 会抛出错误[ts] 'MenuState' only refers to a type, but is being used as a value here. [2693]

function factory(someVar: any) {
    class AClass {
        // Do something with someVar that makes this class unique
    }

    type A = InstanceType<typeof AClass>;
    return A;
}
Run Code Online (Sandbox Code Playgroud)

我该怎么办?一般来说,是否有任何语义上正确的方法来处理类型作为值或变量?如果不是,为什么这违反了 TypeScript 中的最佳实践?此外,如果可能的话,如何将这种类型用作构造函数?

art*_*tem 5

是否有任何语义上正确的方法来处理类型作为值或变量

不。类型只是编译时。将类型表示为在运行时可用的值与此列表中的语言设计非目标 #5 直接矛盾:

在程序中添加或依赖运行时类型信息,或根据类型系统的结果发出不同的代码。相反,鼓励不需要运行时元数据的编程模式。

唯一的例外是类,它们在运行时的表示方式与它们在 es6 javascript 运行时中的表示方式完全相同:作为构造函数。

因此,您可以从函数返回一个类,但该函数将返回一个不能用作类型的值。唯一的例外(有点)是您可以使用函数调用表达式而不是类作为extends.

此外,这个构造

InstanceType<typeof AClass>
Run Code Online (Sandbox Code Playgroud)

被编译器减少到 just AClass,正如T这个类型声明的工具提示中可以看到的那样type T = AClass

type T = InstanceType<typeof AClass>;
Run Code Online (Sandbox Code Playgroud)