Скажите параметру метода, чтобы он принимал только <T>как точную строку - PullRequest
0 голосов
/ 01 апреля 2020

Я хотел бы иметь что-то вроде этого:

SomeAbsClass.getSomething<IMyType>("IMyType");

Итак, как мне кодировать параметр getSomething, чтобы он принимал только точный "IMyType" в качестве строки?

Есть что-то общее с условными типами, в том же ключе, что и , это , но я не могу понять.

1 Ответ

2 голосов
/ 01 апреля 2020

В TypeScript нет внутренней связи между строковыми литеральными типами (например, "IMyType") и именами именованных типов (например, IMyType). Строковые литеральные типы представляют фактические строковые значения, которые существуют во время выполнения, в то время как имена типов соответствуют аспектам системы типов stati c, которая полностью стерта из испущенного JavaScript.

Кроме того, система типов структурная , а не номинальная, поэтому имена типов на самом деле не имеют большого значения. Если я объявлю

type IYourType = IMyType;

, то IYourType и IMyType - это просто два разных имени для одного и того же типа. И поэтому, если SomeAbsClass.getSomething<IYourType>("IYourType"); успешен, тогда SomeAbsClass.getSomething<IMyType>("IYourType"); должен также успешно.

Нет принципиального способа заставить систему типов решить, что одно имя является более "каноническим", чем другое, так что SomeAbsClass.getSomething<IMyType>("IMyType"); завершается успешно и SomeAbsClass.getSomething<IMyType>("IYourType"); завершается неудачей автоматически.


Поскольку это не происходит автоматически, самое близкое, что я могу себе представить - это * ручное создание типа, представляющего желаемое отображение между строковыми литералами и типами, например как:

interface TypeMapping {
    IMyType: IMyType;
    Date: Date;
    string: string;
    boolean: boolean;
    // add whatever you want
}

и затем использовать это отображение в вашем определении getSomething(), например,

declare const SomeAbsClass: {
    getSomething<T>(x: {
        [K in keyof TypeMapping]: TypeMapping[K] extends T ? K : never }[keyof TypeMapping]
    ): void;
}

И вы называете это следующим образом (убедитесь, что явно указали generi c введите параметр при этом):

SomeAbsClass.getSomething<IMyType>("IMyType"); // okay
SomeAbsClass.getSomething<IMyType>("IYourType"); // error

Это работает, насколько это возможно. Подходит ли он для вашего варианта использования - это другая история.


Хорошо, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...