Возвращение типа в качестве переменной в TypeScript - PullRequest
0 голосов
/ 19 января 2019

В настоящее время я пишу фабрику классов в TypeScript и хотел бы вернуть тип в качестве вывода функции. Хотя TypeScript обрабатывает типы в качестве входных данных - т.е. дженерики - прекрасно, я еще не нашел способ обработки типов в качестве вывода.

Этот вопрос StackOverflow на фабриках классов предложил особенно полезное решение, но не полностью ответил на мой вопрос. Учитывая приведенную ниже структуру,

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

вопрос предполагает, что с выходом из этой фабричной функции следует сделать следующее:

import factory from "someLocation";

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

interface IData {
    someField: A;
}

Мне было бы интересно включить эту функцию в мою заводскую функцию, чтобы сделать систему более многоразовой или модульной. Тем не менее, как изначально указывалось, я не уверен, как вернуть тип из функции. Если я попытаюсь сделать следующее, 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;
}

Как я могу пойти по этому поводу? В общем, существует ли какой-либо семантически правильный способ обработки типов как значений или переменных? Если нет, то почему это противоречит лучшей практике в TypeScript? Кроме того, как можно использовать этот тип в качестве конструктора, если это возможно?

1 Ответ

0 голосов
/ 19 января 2019

существует ли какой-либо семантически правильный способ обработки типов как значений или переменных

Нет. Типы только во время компиляции. Представление типов в качестве значений, доступных во время выполнения, находится в прямом противоречии с нецелевой структурой языка № 5 в этом списке :

Добавлять или полагаться на информацию о типах во время выполнения в программах или генерировать другой код на основе результатов системы типов. Вместо этого поощряйте шаблоны программирования, которые не требуют метаданных времени выполнения.

Единственным исключением являются классы, которые представляются во время выполнения точно так же, как они представлены в среде исполнения es6 javascript: как функция конструктора.

Таким образом, вы можете вернуть класс из функции, но функция будет возвращать значение, которое нельзя использовать в качестве типа. Единственное исключение (своего рода) заключается в том, что вы можете использовать выражение вызова функции вместо класса в качестве базового класса в extends.

Также эта конструкция

InstanceType<typeof AClass>

уменьшается компилятором до AClass, что можно увидеть во всплывающей подсказке для T в этого объявления типа , в котором написано type T = AClass

type T = InstanceType<typeof AClass>;
...