diff --git a/.prettierignore b/.prettierignore index 598d2e35c..08bfe99ef 100644 --- a/.prettierignore +++ b/.prettierignore @@ -12,3 +12,5 @@ type-definitions/flow-tests/ !type-definitions/ts-tests/from-js.ts !type-definitions/ts-tests/functional.ts !type-definitions/ts-tests/groupBy.ts +!type-definitions/ts-tests/list.ts +!type-definitions/ts-tests/map.ts diff --git a/tstyche.config.json b/tstyche.config.json index 8ba7a2a9d..250f8f9f7 100644 --- a/tstyche.config.json +++ b/tstyche.config.json @@ -8,6 +8,8 @@ "**/type-definitions/ts-tests/exports.ts", "**/type-definitions/ts-tests/from-js.ts", "**/type-definitions/ts-tests/functional.ts", - "**/type-definitions/ts-tests/groupBy.ts" + "**/type-definitions/ts-tests/groupBy.ts", + "**/type-definitions/ts-tests/list.ts", + "**/type-definitions/ts-tests/map.ts" ] } diff --git a/type-definitions/immutable.d.ts b/type-definitions/immutable.d.ts index bbef59aa2..20fa922f7 100644 --- a/type-definitions/immutable.d.ts +++ b/type-definitions/immutable.d.ts @@ -855,7 +855,9 @@ declare namespace Immutable { get(key: K, notSetValue?: unknown): R[K]; get(key: any, notSetValue: NSV): NSV; - // https://github.com/microsoft/TypeScript/pull/39094 + // TODO `` can be used after dropping support for TypeScript 4.x + // reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#const-type-parameters + // after this change, `as const` assertions can be remove from the type tests getIn

>( searchKeyPath: [...P], notSetValue?: unknown diff --git a/type-definitions/ts-tests/list.ts b/type-definitions/ts-tests/list.ts index 1697d6204..0493364b0 100644 --- a/type-definitions/ts-tests/list.ts +++ b/type-definitions/ts-tests/list.ts @@ -1,7 +1,7 @@ +import { expect, test } from 'tstyche'; import { List, get, - has, set, remove, update, @@ -11,457 +11,387 @@ import { merge, } from 'immutable'; -{ - // #constructor +test('#constructor', () => { + expect(List()).type.toEqual>(); - // $ExpectType List - List(); + expect>().type.toBeAssignable(List()); - const numberList: List = List(); - const numberOrStringList: List = List([1, 'a']); + expect>().type.toBeAssignable(List([1, 'a'])); + expect>().type.not.toBeAssignable(List([1, 'a'])); +}); - // $ExpectError - const invalidNumberList: List = List([1, 'a']); -} +test('#size', () => { + expect(List().size).type.toBeNumber(); -{ - // #size + expect(List()).type.toMatch<{ readonly size: number }>(); +}); - // $ExpectType number - List().size; +test('#setSize', () => { + expect(List().setSize(10)).type.toEqual>(); - // $ExpectError - List().size = 10; -} + expect(List().setSize('foo')).type.toRaiseError(); +}); -{ - // #setSize +test('.of', () => { + expect(List.of(1, 2, 3)).type.toEqual>(); - // $ExpectType List - List().setSize(10); + expect(List.of('a', 1)).type.toRaiseError(); - // $ExpectError - List().setSize('foo'); -} + expect(List.of('a', 1)).type.toEqual< + List + >(); +}); -{ - // .of +test('#get', () => { + expect(List().get(4)).type.toEqual(); - // $ExpectType List - List.of(1, 2, 3); + expect(List().get(4, 'a')).type.toEqual(); - // $ExpectError - List.of('a', 1); + expect(List().get(4, 'a')).type.toRaiseError(); - // $ExpectType List - List.of('a', 1); -} + expect(get(List(), 4)).type.toEqual(); -{ - // #get + expect(get(List(), 4, 'a')).type.toEqual(); +}); - // $ExpectType number | undefined - List().get(4); +test('#set', () => { + expect(List().set(0, 0)).type.toEqual>(); - // $ExpectType number | "a" - List().get(4, 'a'); + expect(List().set(1, 'a')).type.toRaiseError(); - // $ExpectError - List().get(4, 'a'); + expect(List().set('a', 1)).type.toRaiseError(); - // $ExpectType number | undefined - get(List(), 4); + expect(List().set(0, 1)).type.toEqual< + List + >(); - // $ExpectType number | "a" - get(List(), 4, 'a'); -} + expect(List().set(0, 'a')).type.toEqual< + List + >(); -{ - // #set + expect(set(List(), 0, 0)).type.toEqual>(); - // $ExpectType List - List().set(0, 0); + expect(set(List(), 1, 'a')).type.toRaiseError(); - // $ExpectError - List().set(1, 'a'); + expect(set(List(), 'a', 1)).type.toRaiseError(); +}); - // $ExpectError - List().set('a', 1); +test('#setIn', () => { + expect(List().setIn([], 0)).type.toEqual>(); - // $ExpectType List - List().set(0, 1); + expect(setIn(List(), [], 0)).type.toEqual>(); +}); - // $ExpectType List - List().set(0, 'a'); +test('#insert', () => { + expect(List().insert(0, 0)).type.toEqual>(); - // $ExpectType List - set(List(), 0, 0); + expect(List().insert(1, 'a')).type.toRaiseError(); - // $ExpectError - set(List(), 1, 'a'); + expect(List().insert('a', 1)).type.toRaiseError(); - // $ExpectError - set(List(), 'a', 1); -} + expect(List().insert(0, 1)).type.toEqual< + List + >(); -{ - // #setIn + expect(List().insert(0, 'a')).type.toEqual< + List + >(); +}); - // $ExpectType List - List().setIn([], 0); +test('#push', () => { + expect(List().push(0, 0)).type.toEqual>(); - // $ExpectType List - setIn(List(), [], 0); -} + expect(List().push(1, 'a')).type.toRaiseError(); -{ - // #insert + expect(List().push('a', 1)).type.toRaiseError(); - // $ExpectType List - List().insert(0, 0); + expect(List().push(0, 1)).type.toEqual< + List + >(); - // $ExpectError - List().insert(1, 'a'); + expect(List().push(0, 'a')).type.toEqual< + List + >(); +}); - // $ExpectError - List().insert('a', 1); +test('#unshift', () => { + expect(List().unshift(0, 0)).type.toEqual>(); - // $ExpectType List - List().insert(0, 1); + expect(List().unshift(1, 'a')).type.toRaiseError(); - // $ExpectType List - List().insert(0, 'a'); -} + expect(List().unshift('a', 1)).type.toRaiseError(); -{ - // #push + expect(List().unshift(0, 1)).type.toEqual< + List + >(); - // $ExpectType List - List().push(0, 0); + expect(List().unshift(0, 'a')).type.toEqual< + List + >(); +}); - // $ExpectError - List().push(1, 'a'); +test('#delete', () => { + expect(List().delete(0)).type.toEqual>(); - // $ExpectError - List().push('a', 1); + expect(List().delete('a')).type.toRaiseError(); +}); - // $ExpectType List - List().push(0, 1); +test('#deleteIn', () => { + expect(List().deleteIn([])).type.toEqual>(); +}); - // $ExpectType List - List().push(0, 'a'); -} +test('#remove', () => { + expect(List().remove(0)).type.toEqual>(); -{ - // #unshift + expect(List().remove('a')).type.toRaiseError(); - // $ExpectType List - List().unshift(0, 0); + expect(remove(List(), 0)).type.toEqual>(); +}); - // $ExpectError - List().unshift(1, 'a'); +test('#removeIn', () => { + expect(List().removeIn([])).type.toEqual>(); - // $ExpectError - List().unshift('a', 1); + expect(removeIn(List(), [])).type.toEqual>(); +}); - // $ExpectType List - List().unshift(0, 1); +test('#clear', () => { + expect(List().clear()).type.toEqual>(); - // $ExpectType List - List().unshift(0, 'a'); -} + expect(List().clear(10)).type.toRaiseError(); +}); -{ - // #delete +test('#pop', () => { + expect(List().pop()).type.toEqual>(); - // $ExpectType List - List().delete(0); + expect(List().pop(10)).type.toRaiseError(); +}); - // $ExpectError - List().delete('a'); -} +test('#shift', () => { + expect(List().shift()).type.toEqual>(); -{ - // #deleteIn + expect(List().shift(10)).type.toRaiseError(); +}); - // $ExpectType List - List().deleteIn([]); -} +test('#update', () => { + expect(List().update(v => 1)).type.toBeNumber(); -{ - // #remove + expect( + List().update((v: List | undefined) => v) + ).type.toRaiseError(); - // $ExpectType List - List().remove(0); + expect(List().update(0, (v: number | undefined) => 0)).type.toEqual< + List + >(); - // $ExpectError - List().remove('a'); + expect( + List().update(0, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); - // $ExpectType List - remove(List(), 0); -} + expect( + List().update(1, 10, (v: number | undefined) => 0) + ).type.toEqual>(); -{ - // #removeIn + expect( + List().update(1, 'a', (v: number | undefined) => 0) + ).type.toRaiseError(); - // $ExpectType List - List().removeIn([]); + expect( + List().update(1, 10, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); - // $ExpectType List - removeIn(List(), []); -} + expect(List().update(1, v => v?.toUpperCase())).type.toEqual< + List + >(); -{ - // #clear - - // $ExpectType List - List().clear(); - - // $ExpectError - List().clear(10); -} - -{ - // #pop - - // $ExpectType List - List().pop(); - - // $ExpectError - List().pop(10); -} - -{ - // #shift - - // $ExpectType List - List().shift(); - - // $ExpectError - List().shift(10); -} - -{ - // #update - - // $ExpectType number - List().update((v) => 1); - - // $ExpectError - List().update((v: List | undefined) => v); - - // $ExpectType List - List().update(0, (v: number | undefined) => 0); - - // $ExpectError - List().update(0, (v: number | undefined) => v + 'a'); - - // $ExpectType List - List().update(1, 10, (v: number | undefined) => 0); - - // $ExpectError - List().update(1, 'a', (v: number | undefined) => 0); - - // $ExpectError - List().update(1, 10, (v: number | undefined) => v + 'a'); - - // $ExpectType List - List().update(1, (v) => v?.toUpperCase()); - - // $ExpectType List - update(List(), 0, (v: number | undefined) => 0); - - // $ExpectError - update(List(), 1, 10, (v: number) => v + 'a'); -} - -{ - // #updateIn - - // $ExpectType List - List().updateIn([], (v) => v); - - // $ExpectError - List().updateIn([], 10); - - // $ExpectType List - updateIn(List(), [], (v) => v); -} - -{ - // #map - - // $ExpectType List - List().map((value: number, key: number, iter: List) => 1); - - // $ExpectType List - List().map((value: number, key: number, iter: List) => 'a'); - - // $ExpectType List - List().map( - (value: number, key: number, iter: List) => 1 - ); - - List().map( - // $ExpectError - (value: number, key: number, iter: List) => 1 - ); - - List().map( - // $ExpectError - (value: string, key: number, iter: List) => 1 - ); - - List().map( - // $ExpectError - (value: number, key: string, iter: List) => 1 - ); - - List().map( - // $ExpectError - (value: number, key: number, iter: List) => 1 - ); - - List().map( - // $ExpectError - (value: number, key: number, iter: List) => 'a' - ); -} - -{ - // #flatMap - - // $ExpectType List - List().flatMap((value: number, key: number, iter: List) => [ - 1, - ]); - - // $ExpectType List - List().flatMap((value: number, key: number, iter: List) => [ - 'a', - ]); - - // $ExpectType List - List>().flatMap((list) => list); - - // $ExpectType List - List().flatMap( - (value: number, key: number, iter: List) => [1] - ); - - List().flatMap( - // $ExpectError - (value: number, key: number, iter: List) => [1] - ); - - List().flatMap( - // $ExpectError - (value: string, key: number, iter: List) => [1] - ); - - List().flatMap( - // $ExpectError - (value: number, key: string, iter: List) => [1] - ); - - List().flatMap( - // $ExpectError - (value: number, key: number, iter: List) => [1] - ); - - List().flatMap( - // $ExpectError - (value: number, key: number, iter: List) => ['a'] - ); -} - -{ - // #merge - - // $ExpectType List - List().merge(List()); - - // $ExpectType List - List().merge(List()); - - // $ExpectType List - List().merge(List()); - - // $ExpectType List - List().merge(List()); - - // $ExpectType List - merge(List(), List()); -} - -{ - // #mergeIn - - // $ExpectType List - List().mergeIn([], []); -} - -{ - // #mergeDeepIn - - // $ExpectType List - List().mergeDeepIn([], []); -} - -{ - // #flatten - - // $ExpectType Collection - List().flatten(); - - // $ExpectType Collection - List().flatten(10); - - // $ExpectType Collection - List().flatten(false); - - // $ExpectError - List().flatten('a'); -} - -{ - // #withMutations - - // $ExpectType List - List().withMutations((mutable) => mutable); - - // $ExpectError - List().withMutations((mutable: List) => mutable); -} - -{ - // #asMutable - - // $ExpectType List - List().asMutable(); -} - -{ - // #asImmutable - - // $ExpectType List - List().asImmutable(); -} - -{ - // #toJS / #toJSON - - // $ExpectType number[][] - List>().toJS(); - - // $ExpectType List[] - List>().toJSON(); -} - -{ - // # for of loops + expect(update(List(), 0, (v: number | undefined) => 0)).type.toEqual< + List + >(); + + expect( + update(List(), 1, 10, (v: number) => v + 'a') + ).type.toRaiseError(); +}); + +test('#updateIn', () => { + expect(List().updateIn([], v => v)).type.toEqual>(); + + expect(List().updateIn([], 10)).type.toRaiseError(); + + expect(updateIn(List(), [], v => v)).type.toEqual>(); +}); + +test('#map', () => { + expect( + List().map((value: number, key: number, iter: List) => 1) + ).type.toEqual>(); + + expect( + List().map((value: number, key: number, iter: List) => 'a') + ).type.toEqual>(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toEqual>(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: string, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: string, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: number, iter: List) => 1 + ) + ).type.toRaiseError(); + + expect( + List().map( + (value: number, key: number, iter: List) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + List().flatMap((value: number, key: number, iter: List) => [ + 1, + ]) + ).type.toEqual>(); + + expect( + List().flatMap((value: number, key: number, iter: List) => [ + 'a', + ]) + ).type.toEqual>(); + + expect(List>().flatMap(list => list)).type.toEqual< + List + >(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toEqual>(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: string, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: string, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => [1] + ) + ).type.toRaiseError(); + + expect( + List().flatMap( + (value: number, key: number, iter: List) => ['a'] + ) + ).type.toRaiseError(); +}); + +test('#merge', () => { + expect(List().merge(List())).type.toEqual>(); + + expect(List().merge(List())).type.toEqual< + List + >(); + + expect(List().merge(List())).type.toEqual< + List + >(); + + expect(List().merge(List())).type.toEqual< + List + >(); + + expect(merge(List(), List())).type.toEqual>(); +}); + +test('#mergeIn', () => { + expect(List().mergeIn([], [])).type.toEqual>(); +}); + +test('#mergeDeepIn', () => { + expect(List().mergeDeepIn([], [])).type.toEqual>(); +}); + +test('#flatten', () => { + expect(List().flatten()).type.toEqual< + Immutable.Collection + >(); + + expect(List().flatten(10)).type.toEqual< + Immutable.Collection + >(); + + expect(List().flatten(false)).type.toEqual< + Immutable.Collection + >(); + + expect(List().flatten('a')).type.toRaiseError(); +}); + +test('#withMutations', () => { + expect(List().withMutations(mutable => mutable)).type.toEqual< + List + >(); + + expect( + List().withMutations((mutable: List) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(List().asMutable()).type.toEqual>(); +}); + +test('#asImmutable', () => { + expect(List().asImmutable()).type.toEqual>(); +}); + +test('#toJS', () => { + expect(List>().toJSON()).type.toEqual[]>(); +}); + +test('#toJSON', () => { + expect(List>().toJSON()).type.toEqual[]>(); +}); + +test('for of loops', () => { const list = List([1, 2, 3, 4]); + for (const val of list) { - const v: number = val; + expect(val).type.toBeNumber(); } -} +}); diff --git a/type-definitions/ts-tests/map.ts b/type-definitions/ts-tests/map.ts index 39386f67b..dd47bf601 100644 --- a/type-definitions/ts-tests/map.ts +++ b/type-definitions/ts-tests/map.ts @@ -1,631 +1,647 @@ +import { expect, test } from 'tstyche'; import { Map, List, MapOf } from 'immutable'; -{ - // #constructor +test('#constructor', () => { + expect(Map()).type.toEqual>(); - // $ExpectType Map - Map(); + expect(Map()).type.toEqual>(); - // $ExpectType Map - Map(); + expect(Map([[1, 'a']])).type.toEqual>(); - // $ExpectType Map - Map([[1, 'a']]); + expect(Map([['a', 'a']])).type.toEqual>(); - // $ExpectType Map - Map([['a', 'a']]); + expect(Map(List<[number, string]>([[1, 'a']]))).type.toEqual< + Map + >(); - // $ExpectType Map - Map(List<[number, string]>([[1, 'a']])); + expect(Map({ a: 1 })).type.toEqual>(); - // $ExpectType MapOf<{ a: number; }> - Map({ a: 1 }); + expect(Map({ a: 1, b: 'b' })).type.toEqual>(); - // $ExpectType MapOf<{ a: number; b: string; }> - Map({ a: 1, b: 'b' }); + expect(Map({ a: Map({ b: Map({ c: 3 }) }) })).type.toEqual< + MapOf<{ a: MapOf<{ b: MapOf<{ c: number }> }> }> + >(); - // $ExpectType MapOf<{ a: MapOf<{ b: MapOf<{ c: number; }>; }>; }> - Map({ a: Map({ b: Map({ c: 3 }) }) }); + expect(Map<{ a: string }>({ a: 1 })).type.toRaiseError(); - // $ExpectError - Map<{ a: string }>({ a: 1 }); + expect(Map<{ a: string }>({ a: 'a', b: 'b' })).type.toRaiseError(); - // $ExpectError - Map<{ a: string }>({ a: 'a', b: 'b' }); + expect(Map(List([List(['a', 'b'])]))).type.toEqual< + MapOf>> + >(); - // No longer works in typescript@>=3.9 - // // $ExpectError - TypeScript does not support Lists as tuples - // Map(List([List(['a', 'b'])])); + expect(Map<'status', string>({ status: 'paid' })).type.toEqual< + Map<'status', string> + >(); - // $ExpectType Map - const numberMap: Map = Map(); + expect(Map<'status' | 'amount', string>({ status: 'paid' })).type.toEqual< + Map<'status' | 'amount', string> + >(); - // $ExpectType Map<"status", string> - Map<'status', string>({ status: 'paid' }); + expect( + Map<'status', string>({ status: 'paid', amount: 10 }) + ).type.toRaiseError(); +}); - // $ExpectType Map<"status" | "amount", string> - Map<'status' | 'amount', string>({ status: 'paid' }); +test('#size', () => { + expect(Map().size).type.toBeNumber(); - // $ExpectError - Map<'status', string>({ status: 'paid', amount: 10 }); -} + expect(Map()).type.toMatch<{ readonly size: number }>(); +}); -{ - // #size +test('#get', () => { + expect(Map().get(4)).type.toEqual(); - // $ExpectType number - Map().size; + expect(Map().get(4, 'a')).type.toEqual(); - // $ExpectError - Map().size = 10; -} + expect(Map().get(4, 'a')).type.toRaiseError(); -{ - // #get + expect(Map({ a: 4, b: true }).get('a')).type.toBeNumber(); - // $ExpectType number | undefined - Map().get(4); + expect(Map({ a: 4, b: true }).get('b')).type.toBeBoolean(); - // $ExpectType number | "a" - Map().get(4, 'a'); + expect( + Map({ a: Map({ b: true }) }) + .get('a') + .get('b') + ).type.toBeBoolean(); - // $ExpectError - Map().get(4, 'a'); + expect(Map({ a: 4 }).get('b')).type.toRaiseError(); - // $ExpectType number - Map({ a: 4, b: true }).get('a'); + expect(Map({ a: 4 }).get('b', undefined)).type.toBeUndefined(); - // $ExpectType boolean - Map({ a: 4, b: true }).get('b'); + expect(Map({ 1: 4 }).get(1)).type.toBeNumber(); - // $ExpectType boolean - Map({ a: Map({ b: true }) }) - .get('a') - .get('b'); + expect(Map({ 1: 4 }).get(2)).type.toRaiseError(); - // $ExpectError - Map({ a: 4 }).get('b'); + expect(Map({ 1: 4 }).get(2, 3)).type.toEqual<3>(); - // $ExpectType undefined - Map({ a: 4 }).get('b', undefined); + const s1 = Symbol('s1'); - // $ExpectType number - Map({ 1: 4 }).get(1); + expect(Map({ [s1]: 4 }).get(s1)).type.toBeNumber(); - // $ExpectError - Map({ 1: 4 }).get(2); + const s2 = Symbol('s2'); - // $ExpectType 3 - Map({ 1: 4 }).get(2, 3); + expect(Map({ [s2]: 4 }).get(s1)).type.toRaiseError(); +}); - const s = Symbol('s'); +test('#getIn', () => { + expect(Map({ a: 4, b: true }).getIn(['a' as const])).type.toBeNumber(); - // $ExpectType number - Map({ [s]: 4 }).get(s); + expect( + Map({ a: Map({ b: Map({ c: Map({ d: 4 }) }) }) }).getIn([ + 'a' as const, + 'b' as const, + 'c' as const, + 'd' as const, + ]) + ).type.toBeNumber(); - const s2 = Symbol('s2'); + // currently `RetrievePathReducer` does not work with anything else than `MapOf` + expect.fail(Map({ a: List([1]) }).getIn(['a' as const, 0])).type.toBeNumber(); +}); - // $ExpectError - Map({ [s2]: 4 }).get(s); -} +test('#set', () => { + expect(Map().set(0, 0)).type.toEqual>(); -{ - // Minimum TypeScript Version: 4.1 - // #getIn + expect(Map().set(1, 'a')).type.toRaiseError(); - // $ExpectType number - Map({ a: 4, b: true }).getIn(['a']); + expect(Map().set('a', 1)).type.toRaiseError(); - // $ExpectType number - Map({ a: Map({ b: Map({ c: Map({ d: 4 }) }) }) }).getIn(['a', 'b', 'c', 'd']); + expect(Map().set(0, 1)).type.toEqual< + Map + >(); - // with a better type, it should be resolved to `number` in the future. `RetrievePathReducer` does not work with anything else than MapOf - // $ExpectType never - Map({ a: List([ 1 ]) }).getIn(['a', 0]); -} + expect(Map().set(0, 'a')).type.toEqual< + Map + >(); -{ - // #set + expect(Map({ a: 1 }).set('b', 'b')).type.toRaiseError(); - // $ExpectType Map - Map().set(0, 0); + expect(Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b')).type.toEqual< + MapOf<{ a: number; b?: string | undefined }> + >(); - // $ExpectError - Map().set(1, 'a'); + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', undefined) + ).type.toEqual>(); - // $ExpectError - Map().set('a', 1); + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('a') + ).type.toBeNumber(); - // $ExpectType Map - Map().set(0, 1); - - // $ExpectType Map - Map().set(0, 'a'); - - // $ExpectError - Map({ a: 1 }).set('b', 'b'); - - // $ExpectType MapOf<{ a: number; b?: string | undefined; }> - Map<{ a: number; b?: string; }>({ a: 1 }).set('b', 'b'); - - // $ExpectType MapOf<{ a: number; b?: string | undefined; }> - Map<{ a: number; b?: string; }>({ a: 1 }).set('b', undefined); - - // $ExpectType number - Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('a'); - - // $ExpectType string | undefined - Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('b'); + expect( + Map<{ a: number; b?: string }>({ a: 1 }).set('b', 'b').get('b') + ).type.toEqual(); let customer = Map<{ phone: string | number }>({ phone: 'bar', }); - // $ExpectType MapOf<{ phone: string | number; }> - customer = customer.set('phone', 8); -} - -{ - // #setIn - - // $ExpectType Map - Map().setIn([], 0); -} - -{ - // #delete - - // $ExpectType Map - Map().delete(0); - - // $ExpectError - Map().delete('a'); - - // $ExpectType never - Map({ a: 1, b: 'b' }).delete('b'); - - // $ExpectType MapOf<{ a: number; b?: string | undefined; }> - Map<{ a: number; b?: string; }>({ a: 1, b: 'b' }).delete('b'); - - // $ExpectType MapOf<{ a?: number | undefined; b?: string | undefined; }> - Map<{ a?: number; b?: string; }>({ a: 1, b: 'b' }).remove('b').delete('a'); - - // $ExpectType number - Map<{ a: number; b?: string; }>({ a: 1, b: 'b' }).remove('b').get('a'); - - // $ExpectType: string | undefined - Map<{ a: number; b?: string; }>({ a: 1, b: 'b' }).remove('b').get('b'); -} - -{ - // #deleteAll - - // $ExpectType Map - Map().deleteAll([0]); - - // $ExpectError - Map().deleteAll([0, 'a']); -} - -{ - // #deleteIn - - // $ExpectType Map - Map().deleteIn([]); -} - -{ - // #remove - - // $ExpectType Map - Map().remove(0); - - // $ExpectError - Map().remove('a'); -} - -{ - // #removeAll - - // $ExpectType Map - Map().removeAll([0]); - - // $ExpectError - Map().removeAll([0, 'a']); -} - -{ - // #removeIn - - // $ExpectType Map - Map().removeIn([]); -} - -{ - // #clear - - // $ExpectType Map - Map().clear(); - - // $ExpectError - Map().clear(10); -} - -{ - // #update - - // $ExpectType number - Map().update((v) => 1); - - // $ExpectError - Map().update((v: Map | undefined) => v); - - // $ExpectType Map - Map().update(0, (v: number | undefined) => 0); - - // $ExpectError - Map().update(0, (v: number | undefined) => v + 'a'); - - // $ExpectType Map - Map().update(1, 10, (v: number | undefined) => 0); - - // $ExpectError - Map().update(1, 'a', (v: number | undefined) => 0); - - // $ExpectError - Map().update(1, 10, (v: number | undefined) => v + 'a'); - - // $ExpectError - Map({ a: 1, b: 'b' }).update('c', (v) => v); - - // $ExpectType MapOf<{ a: number; b: string; }> - Map({ a: 1, b: 'b' }).update('b', (v) => v.toUpperCase()); - - // $ExpectType MapOf<{ a: number; b: string; }> - Map({ a: 1, b: 'b' }).update('b', 'NSV', (v) => v.toUpperCase()); - - // $ExpectError - Map({ a: 1, b: 'b' }).update((v) => ({ a: 'a' })); - - // $ExpectType MapOf<{ a: number; b: string; }> - Map({ a: 1, b: 'b' }).update((v) => v.set('a', 2).set('b', 'B')); - - // $ExpectError - Map({ a: 1, b: 'b' }).update((v) => v.set('c', 'c')); - - // $ExpectType Map - Map().update("noKey", ls => ls?.toUpperCase()); -} - -{ - // #updateIn - - // $ExpectType Map - Map().updateIn([], (v) => v); - - // $ExpectError - Map().updateIn([], 10); -} - -{ - // #map - - // $ExpectType Map - Map().map( - (value: number, key: number, iter: Map) => 1 - ); - - // $ExpectType Map - Map().map( - (value: number, key: number, iter: Map) => 'a' - ); - - // $ExpectType Map - Map().map( - (value: number, key: number, iter: Map) => 1 - ); - - Map().map( - // $ExpectError - (value: number, key: number, iter: Map) => 1 - ); - - Map().map( - // $ExpectError - (value: string, key: number, iter: Map) => 1 - ); - - Map().map( - // $ExpectError - (value: number, key: string, iter: Map) => 1 - ); - - Map().map( - // $ExpectError - (value: number, key: number, iter: Map) => 1 - ); - - Map().map( - // $ExpectError - (value: number, key: number, iter: Map) => 'a' - ); -} - -{ - // #mapKeys - - // $ExpectType Map - Map().mapKeys( - (value: number, key: number, iter: Map) => 1 - ); - - // $ExpectType Map - Map().mapKeys( - (value: number, key: number, iter: Map) => 'a' - ); - - // $ExpectType Map - Map().mapKeys( - (value: number, key: number, iter: Map) => 1 - ); - - Map().mapKeys( - // $ExpectError - (value: number, key: number, iter: Map) => 1 - ); - - Map().mapKeys( - // $ExpectError - (value: string, key: number, iter: Map) => 1 - ); - - Map().mapKeys( - // $ExpectError - (value: number, key: string, iter: Map) => 1 - ); - - Map().mapKeys( - // $ExpectError - (value: number, key: number, iter: Map) => 1 - ); - - Map().mapKeys( - // $ExpectError - (value: number, key: number, iter: Map) => 'a' - ); -} - -{ - // #flatMap - - // $ExpectType Map - Map().flatMap( - (value: number, key: number, iter: Map) => [[0, 1]] - ); - - // $ExpectType Map - Map().flatMap( - (value: number, key: number, iter: Map) => [['a', 'b']] - ); - - // $ExpectType Map - Map().flatMap( - (value: number, key: number, iter: Map) => [[0, 1]] - ); - - Map().flatMap( - // $ExpectError - (value: number, key: number, iter: Map) => [[0, 1]] - ); - - Map().flatMap( - // $ExpectError - (value: string, key: number, iter: Map) => [[0, 1]] - ); - - Map().flatMap( - // $ExpectError - (value: number, key: string, iter: Map) => [[0, 1]] - ); - - Map().flatMap( - // $ExpectError - (value: number, key: number, iter: Map) => [[0, 1]] - ); - - Map().flatMap( - // $ExpectError - (value: number, key: number, iter: Map) => [[0, 'a']] - ); -} - -{ - // #merge - - // $ExpectType Map - Map().merge({ a: 1 }); - - // $ExpectType Map - Map().merge({ a: { b: 1 } }); - - // $ExpectType Map - Map().merge(Map()); - - // $ExpectType Map - Map().merge(Map()); - - // $ExpectType Map - Map().merge(Map()); - - // $ExpectType Map - Map().merge(Map()); - - // $ExpectType Map<"b" | "a", number> - Map({ a: 1 }).merge(Map({ b: 2 })); -} - -{ - // #mergeIn - - // $ExpectType Map - Map().mergeIn([], []); -} - -{ - // #mergeWith - - // $ExpectType Map - Map().mergeWith( - (prev: number, next: number, key: number) => 1, - Map() - ); - - Map().mergeWith( - // $ExpectError - (prev: string, next: number, key: number) => 1, - Map() - ); - - // $ExpectError - Map().mergeWith( - (prev: number, next: string, key: number) => 1, - Map() - ); - - // $ExpectError - Map().mergeWith( - (prev: number, next: number, key: string) => 1, - Map() - ); - - // $ExpectType Map - Map().mergeWith( - (prev: number, next: number, key: number) => 'a', - Map() - ); - - // $ExpectError - Map().mergeWith( - (prev: number, next: number, key: number) => 1, - Map() - ); - - // $ExpectType Map - Map().mergeWith( - (prev: number, next: number, key: string) => 1, - { a: 1 } - ); - - Map().mergeWith( - (prev: number, next: number, key: string) => 1, - // $ExpectError - { a: 'a' } - ); - - // $ExpectType Map - Map().mergeWith( - (prev: number, next: number | string, key: string) => 1, - { a: 'a' } - ); - - // $ExpectType Map - Map().mergeWith((prev: number | string, next: number | string, key: number) => 1, Map()); -} - -{ - // #mergeDeep - - // $ExpectType Map - Map().mergeDeep({ a: 1 }); - - // $ExpectType Map - Map().mergeDeep({ a: { b: 1 } }); - - // $ExpectType Map - Map().mergeDeep(Map({ a: { b: 1 } })); - - // $ExpectType Map - Map().mergeDeep(Map()); - - // $ExpectType Map - Map().mergeDeep(Map()); - - // $ExpectType Map - Map().mergeDeep(Map()); - - // $ExpectType Map - Map().mergeDeep(Map()); -} - -{ - // #mergeDeepIn - - // $ExpectType Map - Map().mergeDeepIn([], []); -} - -{ - // #mergeDeepWith - - // $ExpectType Map - Map().mergeDeepWith((prev: unknown, next: unknown, key: unknown) => 1, Map()); - - // $ExpectError - Map().mergeDeepWith((prev: unknown, next: unknown, key: unknown) => 1, Map()); + expect(customer).type.toBeAssignable(customer.set('phone', 8)); +}); - // $ExpectType Map - Map().mergeDeepWith((prev: unknown, next: unknown, key: unknown) => 1, { a: 1 }); +test('#setIn', () => { + expect(Map().setIn([], 0)).type.toEqual< + Map + >(); +}); - // $ExpectError - Map().mergeDeepWith((prev: unknown, next: unknown, key: unknown) => 1, { a: 'a' }); +test('#delete', () => { + expect(Map().delete(0)).type.toEqual>(); - // $ExpectType Map - Map().mergeDeepWith((prev: unknown, next: unknown, key: unknown) => 1, Map()); -} + expect(Map().delete('a')).type.toRaiseError(); -{ - // #flip + expect(Map({ a: 1, b: 'b' }).delete('b')).type.toBeNever(); - // $ExpectType Map - Map().flip(); -} + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).delete('b') + ).type.toEqual>(); -{ - // #withMutations + expect( + Map<{ a?: number; b?: string }>({ a: 1, b: 'b' }).remove('b').delete('a') + ).type.toEqual>(); - // $ExpectType Map - Map().withMutations((mutable) => mutable); + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).remove('b').get('a') + ).type.toBeNumber(); - // $ExpectError - Map().withMutations((mutable: Map) => mutable); -} + expect( + Map<{ a: number; b?: string }>({ a: 1, b: 'b' }).remove('b').get('b') + ).type.toEqual(); +}); -{ - // #asMutable +test('#deleteAll', () => { + expect(Map().deleteAll([0])).type.toEqual< + Map + >(); - // $ExpectType Map - Map().asMutable(); -} + expect(Map().deleteAll([0, 'a'])).type.toRaiseError(); +}); -{ - // #asImmutable +test('#deleteIn', () => { + expect(Map().deleteIn([])).type.toEqual< + Map + >(); +}); - // $ExpectType Map - Map().asImmutable(); -} +test('#remove', () => { + expect(Map().remove(0)).type.toEqual>(); -{ - // #toJS / #toJSON + expect(Map().remove('a')).type.toRaiseError(); +}); - // $ExpectType { [x: string]: number; [x: number]: number; [x: symbol]: number; } - Map().toJS(); +test('#removeAll', () => { + expect(Map().removeAll([0])).type.toEqual< + Map + >(); - // $ExpectType { a: string; } - Map({ a: 'A' }).toJS(); + expect(Map().removeAll([0, 'a'])).type.toRaiseError(); +}); - // $ExpectType { a: { b: string; }; } - Map({ a: Map({ b: 'b' }) }).toJS(); +test('#removeIn', () => { + expect(Map().removeIn([])).type.toEqual< + Map + >(); +}); + +test('#clear', () => { + expect(Map().clear()).type.toEqual>(); - // $ExpectType { a: MapOf<{ b: string; }>; } - Map({ a: Map({ b: 'b' }) }).toJSON(); -} + expect(Map().clear(10)).type.toRaiseError(); +}); + +test('#update', () => { + expect(Map().update(v => 1)).type.toBeNumber(); + + expect( + Map().update((v: Map | undefined) => v) + ).type.toRaiseError(); + + expect( + Map().update(0, (v: number | undefined) => 0) + ).type.toEqual>(); + + expect( + Map().update(0, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect( + Map().update(1, 10, (v: number | undefined) => 0) + ).type.toEqual>(); + + expect( + Map().update(1, 'a', (v: number | undefined) => 0) + ).type.toRaiseError(); + + expect( + Map().update(1, 10, (v: number | undefined) => v + 'a') + ).type.toRaiseError(); + + expect(Map({ a: 1, b: 'b' }).update('c', v => v)).type.toRaiseError(); + + expect(Map({ a: 1, b: 'b' }).update('b', v => v.toUpperCase())).type.toEqual< + MapOf<{ a: number; b: string }> + >(); + + expect( + Map({ a: 1, b: 'b' }).update('b', 'NSV', v => v.toUpperCase()) + ).type.toEqual>(); + + expect(Map({ a: 1, b: 'b' }).update(v => ({ a: 'a' }))).type.toRaiseError(); + + expect( + Map({ a: 1, b: 'b' }).update(v => v.set('a', 2).set('b', 'B')) + ).type.toEqual>(); + + expect( + Map({ a: 1, b: 'b' }).update(v => v.set('c', 'c')) + ).type.toRaiseError(); + + expect( + Map().update('noKey', ls => ls?.toUpperCase()) + ).type.toEqual>(); +}); + +test('#updateIn', () => { + expect(Map().updateIn([], v => v)).type.toEqual< + Map + >(); + + expect(Map().updateIn([], 10)).type.toRaiseError(); +}); + +test('#map', () => { + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toEqual>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toEqual>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toEqual>(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: string, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: string, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().map( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#mapKeys', () => { + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toEqual>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toEqual>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toEqual>(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: string, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: string, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 1 + ) + ).type.toRaiseError(); + + expect( + Map().mapKeys( + (value: number, key: number, iter: Map) => 'a' + ) + ).type.toRaiseError(); +}); + +test('#flatMap', () => { + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toEqual>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [['a', 'b']] + ) + ).type.toEqual>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toEqual>(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: string, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: string, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 1]] + ) + ).type.toRaiseError(); + + expect( + Map().flatMap( + (value: number, key: number, iter: Map) => [[0, 'a']] + ) + ).type.toRaiseError(); +}); + +test('#merge', () => { + expect(Map().merge({ a: 1 })).type.toEqual< + Map + >(); + + expect(Map().merge({ a: { b: 1 } })).type.toEqual< + Map + >(); + + expect(Map().merge(Map())).type.toEqual< + Map + >(); + + expect(Map().merge(Map())).type.toEqual< + Map + >(); + + expect( + Map().merge(Map()) + ).type.toEqual>(); + + expect( + Map().merge(Map()) + ).type.toEqual>(); + + expect(Map({ a: 1 }).merge(Map({ b: 2 }))).type.toEqual< + Map<'b' | 'a', number> + >(); +}); + +test('#mergeIn', () => { + expect(Map().mergeIn([], [])).type.toEqual< + Map + >(); +}); + +test('#mergeWith', () => { + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 1, + Map() + ) + ).type.toEqual>(); + + expect( + Map().mergeWith( + (prev: string, next: number, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: string, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 'a', + Map() + ) + ).type.toEqual>(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: number) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 1 } + ) + ).type.toEqual>(); + + expect( + Map().mergeWith( + (prev: number, next: number, key: string) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + Map().mergeWith( + (prev: number, next: number | string, key: string) => 1, + { a: 'a' } + ) + ).type.toEqual>(); + + expect( + Map().mergeWith( + (prev: number | string, next: number | string, key: number) => 1, + Map() + ) + ).type.toEqual>(); +}); + +test('#mergeDeep', () => { + expect(Map().mergeDeep({ a: 1 })).type.toEqual< + Map + >(); + + expect(Map().mergeDeep({ a: { b: 1 } })).type.toEqual< + Map + >(); + + expect(Map().mergeDeep(Map({ a: { b: 1 } }))).type.toEqual< + Map + >(); + + expect(Map().mergeDeep(Map())).type.toEqual< + Map + >(); + + expect(Map().mergeDeep(Map())).type.toEqual< + Map + >(); + + expect( + Map().mergeDeep(Map()) + ).type.toEqual>(); + + expect( + Map().mergeDeep(Map()) + ).type.toEqual>(); +}); + +test('#mergeDeepIn', () => { + expect(Map().mergeDeepIn([], [])).type.toEqual< + Map + >(); +}); + +test('#mergeDeepWith', () => { + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toEqual>(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toRaiseError(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 1 } + ) + ).type.toEqual>(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + { a: 'a' } + ) + ).type.toRaiseError(); + + expect( + Map().mergeDeepWith( + (prev: unknown, next: unknown, key: unknown) => 1, + Map() + ) + ).type.toEqual>(); +}); + +test('#flip', () => { + expect(Map().flip()).type.toEqual>(); +}); + +test('#withMutations', () => { + expect(Map().withMutations(mutable => mutable)).type.toEqual< + Map + >(); + + expect( + Map().withMutations((mutable: Map) => mutable) + ).type.toRaiseError(); +}); + +test('#asMutable', () => { + expect(Map().asMutable()).type.toEqual>(); +}); + +test('#asImmutable', () => { + expect(Map().asImmutable()).type.toEqual< + Map + >(); +}); + +test('#toJS', () => { + expect(Map().toJS()).type.toEqual<{ + [x: string]: number; + [x: number]: number; + [x: symbol]: number; + }>(); + + expect(Map({ a: 'A' }).toJS()).type.toEqual<{ a: string }>(); + + expect(Map({ a: Map({ b: 'b' }) }).toJS()).type.toEqual<{ + a: { b: string }; + }>(); +}); + +test('#toJSON', () => { + expect(Map({ a: Map({ b: 'b' }) }).toJSON()).type.toEqual<{ + a: MapOf<{ b: string }>; + }>(); +}); diff --git a/type-definitions/ts-tests/tslint.json b/type-definitions/ts-tests/tslint.json index 84b746b11..29eca5bdd 100644 --- a/type-definitions/ts-tests/tslint.json +++ b/type-definitions/ts-tests/tslint.json @@ -9,7 +9,9 @@ "exports.ts", "from-js.ts", "functional.ts", - "groupBy.ts" + "groupBy.ts", + "list.ts", + "map.ts" ] }, "rules": {