如何解决“类型循环引用自身错误”?

问题描述

下面是一个预期结果的示例:

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并正确引用下面的常量

TypeScript版本4.0.2

游乐场link

解决方法

以下应该有效:

您的方法有两个主要区别:

  • 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 Playground