Skip to content

Type recursion limit (TS2589) on recursive mapped types #4055

Description

@blickly

Steps to reproduce

main.ts

import {type Conversation} from './types';

type PrimitiveType = number | string | boolean;

export type WritableDraft<T> = {-readonly [K in keyof T]: Draft<T[K]>};

export type Draft<T> = T extends PrimitiveType
  ? T
  : T extends object
  ? WritableDraft<T>
  : T;

export interface OnlyConversationState {
  currentConversation?: Conversation;
}

// Triggers the recursion error on assignment in TSgo
export function test(state: Draft<OnlyConversationState>, payload: Conversation | undefined) {
  state.currentConversation = payload;
}

types.ts

export type DataValue = string | DataObject | DataArray;

export interface DataObject {
  [key: string]: DataValue;
}
export type DataArray = DataValue[];

export type ValueMap = DataObject & {
  valueMap?: ValueMap[];
};

export interface DataModelUpdate {
  contents: ValueMap[];
}

export interface ServerToClientMessage {
  dataModelUpdate?: DataModelUpdate;
}

export interface Answer {
  a2uiMessages?: ServerToClientMessage[];
}

export interface Conversation {
  messages: Answer[];
}

Behavior with typescript@6.0

Typechecks with no error, even with stableTypeOrdering set

Playground Link

Behavior with tsgo

error TS2589: Type instantiation is excessively deep and possibly infinite.

Playground Link

Metadata

Metadata

Labels

wontfixThis will not be worked on

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions