#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'
Комментарии:
1. У вас все еще есть те же ошибки, можете ли вы опубликовать ссылку repl?
2. Добавлено в ответ, это может быть проблема с версией. Это работает при ночной сборке typescript. Похоже, они что-то исправили в nightly
3. Ссылка указывает на неполный пример, но вы правы!
4. Спасибо, я немного усложнил пример , чтобы посмотреть, выполняется ли решение, и оно выполняется.