diff --git a/CHANGELOG.md b/CHANGELOG.md index 1369d0638..72f13794c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Dates are formatted as YYYY-MM-DD. +## Unreleased + +- [Typescript] rollback some of the change on `toJS` to avoir circular reference + ## [4.2.0] - 2022-12-22 - [TypeScript] Better type for toJS [#1917](https://github.com/immutable-js/immutable-js/pull/1917) by [jdeniau](https://github.com/jdeniau) diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts index 7adfdeb38..bf21c42bf 100644 --- a/type-definitions/immutable.d.ts +++ b/type-definitions/immutable.d.ts @@ -93,24 +93,34 @@ declare namespace Immutable { /** * @ignore + * + * Used to convert deeply all immutable types to a plain TS type. + * Using `unknown` on object instead of recursive call as we have a circular reference issue */ - export type DeepCopy = T extends Collection.Keyed + export type DeepCopy = T extends Record + ? // convert Record to DeepCopy plain JS object + { + [key in keyof R]: R[key] extends object ? unknown : R[key]; + } + : T extends Collection.Keyed ? // convert KeyedCollection to DeepCopy plain JS object { [key in KeyedKey extends string | number | symbol ? KeyedKey - : string]: DeepCopy; + : string]: V extends object ? unknown : V; } : // convert IndexedCollection or Immutable.Set to DeepCopy plain JS array T extends Collection - ? Array> + ? Array : T extends string | number // Iterable scalar types : should be kept as is ? T : T extends Iterable // Iterable are converted to plain JS array - ? Array> + ? Array : T extends object // plain JS object are converted deeply ? { - [ObjectKey in keyof T]: DeepCopy; + [ObjectKey in keyof T]: T[ObjectKey] extends object + ? unknown + : T[ObjectKey]; } : // other case : should be kept as is T; diff --git a/type-definitions/ts-tests/deepCopy.ts b/type-definitions/ts-tests/deepCopy.ts index 3012e0ffc..2f16c983d 100644 --- a/type-definitions/ts-tests/deepCopy.ts +++ b/type-definitions/ts-tests/deepCopy.ts @@ -5,11 +5,6 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; // $ExpectType { a: number; b: number; } type Test = DeepCopy<{ a: number; b: number }>; - // ^? - - // $ExpectType number - type TestA = Test['a']; - // ^? } { @@ -17,11 +12,9 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; // $ExpectType string[] type Test = DeepCopy; - // ^? // $ExpectType number[] type Keyed = DeepCopy>; - // ^? } { @@ -30,10 +23,12 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; // $ExpectType { [x: string]: string; } type StringKey = DeepCopy>; - // $ExpectType { [x: string]: object; } + // should be `{ [x: string]: object; }` but there is an issue with circular references + // $ExpectType { [x: string]: unknown; } type ObjectKey = DeepCopy>; - // $ExpectType { [x: string]: object; [x: number]: object; } + // should be `{ [x: string]: object; [x: number]: object; }` but there is an issue with circular references + // $ExpectType { [x: string]: unknown; [x: number]: unknown; } type MixedKey = DeepCopy>; // $ExpectType string[] @@ -62,9 +57,23 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; { // Nested - // $ExpectType { map: { [x: string]: string; }; list: string[]; set: string[]; } + // should be `{ map: { [x: string]: string; }; list: string[]; set: string[]; }` but there is an issue with circular references + // $ExpectType { map: unknown; list: unknown; set: unknown; } type NestedObject = DeepCopy<{ map: Map; list: List; set: Set; }>; - // $ExpectType { map: { [x: string]: string; }; } + // should be `{ map: { [x: string]: string; }; }`, but there is an issue with circular references + // $ExpectType { map: unknown; } type NestedMap = DeepCopy>>; } + +{ + // Circular references + + type Article = Record<{ title: string; tag: Tag; }>; + type Tag = Record<{ name: string; article: Article; }>; + + // should handle circular references here somehow + // $ExpectType { title: string; tag: unknown; } + type Circular = DeepCopy
; + // ^? +} diff --git a/type-definitions/ts-tests/record.ts b/type-definitions/ts-tests/record.ts index 7a626e438..38da1148e 100644 --- a/type-definitions/ts-tests/record.ts +++ b/type-definitions/ts-tests/record.ts @@ -88,6 +88,7 @@ import { List, Map, Record, Set } from 'immutable'; // $ExpectType { map: Map; list: List; set: Set; } withMap.toJSON(); - // $ExpectType { map: { [x: string]: string; }; list: string[]; set: string[]; } + // should be `{ map: { [x: string]: string; }; list: string[]; set: string[]; }` but there is an issue with circular references + // $ExpectType { map: unknown; list: unknown; set: unknown; } withMap.toJS(); }