установить тип свойства на основе значения типа enum - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть тип FieldType, который является перечислением, и FieldTypeToTSType, который получает FieldType в качестве параметра и преобразует его в тип машинописного текста.


type FieldType = "string" | "int";

type FieldTypeToTSType<T extends FieldType> = 
    T extends "string" ? string
  : T extends "int" ? number
  : never;

, но проблема заключается в использовании он напрямую работает:

FieldTypeToTSType<"string"> // string
FieldTypeToTSType<"int"> // number

, но когда я использую FieldType, он всегда определяет его как строку

const a: FieldType = "int";

type K = FieldTypeToTSType<typeof a>; // string but it should be number

контекст, в котором я его использую:

type FieldType = "string" | "int";
type FieldDefinition = {
  type: FieldType;
};

type EntityDefinition<T> = {
  [K in keyof T]: FieldDefinition;
};

const makeEntity = <T>(et: { [K in keyof T]: FieldDefinition }) => et;

type FieldTypeToTSType<T extends FieldType> = T extends "string"
  ? string
  : T extends "int"
  ? number
  : never;

type EntityRefrence<T extends EntityDefinition<T>, R extends keyof T = keyof T> = {
  [key in R]: FieldTypeToTSType<T[R]["type"]>;
};

const Vacation = makeEntity({
  days: {
    type: "int",
  },
  name: {
    type: "string"
  }
});

type VacationRef = EntityRefrence<typeof Vacation>;

Тип VacationRef должен быть

type VacationRef = {
    days: number;
    name: string;
}

, но это:

type VacationRef = {
    days: string | number;
    name: string | number;
}

1 Ответ

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

Это не работает, потому что FieldType исходного объекта расширен в makeEntity и EntityRefrence. Чтобы исправить это в EntityRefrence - используйте специфицированный ключ c вместо объединения всех возможных ключей:

type EntityRefrence<T extends EntityDefinition<T>> = {
  [key in keyof T]: FieldTypeToTSType<T[key]["type"]>;
};

В makeEntity - переданный параметр должен иметь тип generi c, поэтому его тип должен быть корректным выведены и не расширены:

const makeEntity = <T extends { [K in keyof T]: FieldDefinition }>(et: T) => et;

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

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