Как устранить ошибку «Тип по кругу ссылается на саму ошибку»?

#typescript #circular-reference

#typescript #циклическая ссылка

Вопрос:

Ниже приведен пример проблемы с ожидаемым результатом:

 const actionTypes = {
  name: {
    set: "name/set",
  },
} as const;

type ActionTypes = { [key: string]: (string | ActionTypes) }; //record value is string or ActionTypes

// "GetActionType" circularly references itself
type GetActionType<A extends ActionTypes> = A extends Record<
  string,
  infer Value
>
  ? Value extends string
    ? Value
    : GetActionType<Value> // "GetActionType" is not generic
  : unknown;

type SiteAction = GetActionType<typeof actionTypes>; // "GetActionType" is not generic
// expected to be 'name/set'

  

Есть ли способ выполнить это, не сталкиваясь с ошибкой?

Редактировать

Добавляет as const к объявлению ActionTypes и правильно ссылается на константу ниже

Версия TypeScript 4.0.2

Ссылка на игровую площадку.

Ответ №1:

Должно сработать следующее:

Два основных отличия от вашего подхода:

  • перевернуто Value extends string в Value extends ActionTypes для рекурсии
  • помечено siteActionTypes для as const определения конкретных типов
 const siteActionTypes = {
  name: {
    set: 'name/set'
  }
} as const

type ActionTypes = { [key: string]: string | ActionTypes }

type GetActionType<A extends ActionTypes> = A extends Record<string, infer Value>
  ? Value extends ActionTypes
    ? GetActionType<Value>
    : Value
  : unknown

type SiteAction = GetActionType<typeof siteActionTypes>
// SiteAction has type 'name/set'

  

Игровая площадка Typescript

Комментарии:

1. У вас все еще есть те же ошибки, можете ли вы опубликовать ссылку repl?

2. Добавлено в ответ, это может быть проблема с версией. Это работает при ночной сборке typescript. Похоже, они что-то исправили в nightly

3. Ссылка указывает на неполный пример, но вы правы!

4. Спасибо, я немного усложнил пример , чтобы посмотреть, выполняется ли решение, и оно выполняется.