diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts index f343aa06f..c47181a2c 100644 --- a/type-definitions/immutable.d.ts +++ b/type-definitions/immutable.d.ts @@ -100,27 +100,25 @@ declare namespace Immutable { export type DeepCopy = T extends Record ? // convert Record to DeepCopy plain JS object { - [key in keyof R]: R[key] extends object ? unknown : R[key]; + [key in keyof R]: DeepCopy; } : T extends Collection.Keyed ? // convert KeyedCollection to DeepCopy plain JS object { [key in KeyedKey extends string | number | symbol ? KeyedKey - : string]: V extends object ? unknown : V; + : string]: DeepCopy; } : // 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]: T[ObjectKey] extends object - ? unknown - : T[ObjectKey]; + [ObjectKey in keyof T]: DeepCopy; } : // 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 2f16c983d..dc64f1533 100644 --- a/type-definitions/ts-tests/deepCopy.ts +++ b/type-definitions/ts-tests/deepCopy.ts @@ -23,12 +23,10 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; // $ExpectType { [x: string]: string; } type StringKey = DeepCopy>; - // should be `{ [x: string]: object; }` but there is an issue with circular references - // $ExpectType { [x: string]: unknown; } + // $ExpectType { [x: string]: object; } type ObjectKey = DeepCopy>; - // should be `{ [x: string]: object; [x: number]: object; }` but there is an issue with circular references - // $ExpectType { [x: string]: unknown; [x: number]: unknown; } + // $ExpectType { [x: string]: object; [x: number]: object; } type MixedKey = DeepCopy>; // $ExpectType string[] @@ -57,12 +55,10 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; { // Nested - // 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; } + // $ExpectType { map: { [x: string]: string; }; list: string[]; set: string[]; } type NestedObject = DeepCopy<{ map: Map; list: List; set: Set; }>; - // should be `{ map: { [x: string]: string; }; }`, but there is an issue with circular references - // $ExpectType { map: unknown; } + // $ExpectType { map: { [x: string]: string; }; } type NestedMap = DeepCopy>>; } @@ -72,8 +68,6 @@ import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable'; 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; } + // $ExpectType { title: string; tag: { name: string; article: any; }; } type Circular = DeepCopy
; - // ^? } diff --git a/type-definitions/ts-tests/record.ts b/type-definitions/ts-tests/record.ts index 38da1148e..c245cf310 100644 --- a/type-definitions/ts-tests/record.ts +++ b/type-definitions/ts-tests/record.ts @@ -1,4 +1,4 @@ -import { List, Map, Record, Set } from 'immutable'; +import { List, Map, Record, RecordOf, Set } from 'immutable'; { // Factory @@ -88,7 +88,31 @@ import { List, Map, Record, Set } from 'immutable'; // $ExpectType { map: Map; list: List; set: Set; } withMap.toJSON(); - // 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; } + // $ExpectType { map: { [x: string]: string; }; list: string[]; set: string[]; } withMap.toJS(); } + +{ + // optional properties + + interface Size { distance: string; } + + const Line = Record<{ size?: Size, color?: string }>({ size: undefined, color: 'red' }); + + const line = Line({}); + + // $ExpectType { size?: { distance: string; } | undefined; color?: string | undefined; } + line.toJS(); +} + +{ + // similar properties, but one is optional. See https://github.com/immutable-js/immutable-js/issues/1930 + + interface Id { value: string; } + + type A = RecordOf<{ id: Id }>; + type B = RecordOf<{ id?: Id }>; + + const a: A = null as any; + const b: B = a; +}