Returning a Type as a Variable in TypeScript

妖精的绣舞 提交于 2020-07-10 06:23:00

问题


I'm currently writing a class factory in TypeScript, and would like to return a type as the output of a function. Although TypeScript handles types as an input--i.e. generics--beautifully, I've not yet found a way to handle types as an output.

This StackOverflow question on class factories offered a particularly helpful solution, but did not fully answer my question. Given the below structure,

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

the question suggests that one should do the following with the output from this factory function:

import factory from "someLocation";

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

interface IData {
    someField: A;
}

I'd be interested in including this functionality in my factory function to make the system more reusable or modular. However, as initially stated, I'm unsure of how to return a type from a function. If I attempt the following, TypeScript throws the error, [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;
}

How might I go about this? In general, is there any semantically correct way to handle types as values or variables? If not, why does this violate best practice in TypeScript? Furthermore, how might one then use this type as a constructor, if possible?


回答1:


is there any semantically correct way to handle types as values or variables

No. Types are compile-time only. Representing types as values, available at run-time is in the direct contradiction to the language design non-goal #5 in this list:

Add or rely on run-time type information in programs, or emit different code based on the results of the type system. Instead, encourage programming patterns that do not require run-time metadata.

The only exception are classes, which are represented at run-time exactly in the same way they are represented in es6 javascript runtime: as constructor function.

So you can return a class from a function, but the function will be returning a value, which can't be used as a type. The only exception (sort of) is that you can use a function-call expression instead of a class as a base class in extends.

Also, this construct

InstanceType<typeof AClass>

is reduced by the compiler to just AClass, as can be seen in a tooltip for T in this type declaration which says type T = AClass

type T = InstanceType<typeof AClass>;


来源:https://stackoverflow.com/questions/54263504/returning-a-type-as-a-variable-in-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!