Returning a Type as a Variable in TypeScript

问题: 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. generi...

问题:

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>;
  • 发表于 2019-01-21 01:43
  • 阅读 ( 237 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除