Repository: immutable-js/immutable-js
Pull request #1988 (2024-02-21 09:41:56)

Migrate type tests to TSTyche
Reference https://github.com/immutable-js/immutable-js/issues/1985#issuecomment-1956085576

This PR migrates two type test files to TSTyche. The setup is painless and migration can be done gradually. Hope this makes it easier to review.

The test files were not passed through Prettier before (probably because of some conflict).

Good question: how CI checks should be setup? To test on different versions of TypeScript, I used TSTyche's `target` option. This makes local runs noisy. It would be enough to have `test:types --target 4.5,5.0,current` in CI. @jdeniau what you think?

mrazauskas: Two more smaller files are added. Sorry, I just couldn’t stop (;

How is it better: to push all tests here? or, to wait until this PR will be merged?
jdeniau: > Two more smaller files are added. Sorry, I just couldn’t stop (;
> 
> How is it better: to push all tests here? or, to wait until this PR will be merged?

If you are on fire, just push it here, and tell me when you want me to review 😄 
If you handle to remove dtslint, it's perfect 🎉 

The only thing is I need to manually trigger a "run" because of the project configuration, so I'll do it when I can,  but you might be faster than me.
mrazauskas: Would be nicer, if CI could run automatically.

All checks are green at the moment. Let’s merge this one, if all looks good for you. I see that in larger files I will have some questions. Would be easier to go through these in separate PRs.
jdeniau: Merging this as everything is OK and the transition is promising

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6d61ec989..41349ebbc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -50,8 +50,8 @@ jobs:
       - run: npm run type-check
       - run: npm run check-git-clean
 
-  unit-test:
-    name: 'Build & Unit Test'
+  test:
+    name: 'Build & Unit Test & Type Test'
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
@@ -65,7 +65,8 @@ jobs:
           restore-keys: ${{ runner.OS }}-node-
       - run: npm ci
       - run: npm run build
-      - run: npm run unit-test
+      - run: npm run test:unit
+      - run: npm run test:types -- --target 4.5,5.0,current
       - run: npx size-limit
       - run: npm run check-git-clean
 
@@ -90,7 +91,7 @@ jobs:
 
   publish:
     name: 'Publish'
-    needs: [lint, type-check, unit-test, website]
+    needs: [lint, type-check, test, website]
     if: github.ref == 'refs/heads/main'
     runs-on: ubuntu-latest
     steps:
diff --git a/.prettierignore b/.prettierignore
index 407b338f4..5ee00f8c0 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,5 +1,10 @@
 dist
 pages/generated
 pages/out
-type-definitions/ts-tests/
-type-definitions/flow-tests/
\ No newline at end of file
+type-definitions/ts-tests/*.ts
+type-definitions/flow-tests/
+
+!type-definitions/ts-tests/covariance.ts
+!type-definitions/ts-tests/deepCopy.ts
+!type-definitions/ts-tests/empty.ts
+!type-definitions/ts-tests/es6-collections.ts
diff --git a/package-lock.json b/package-lock.json
index 92c1391e5..a87967ffc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -53,6 +53,7 @@
         "rollup": "3.28.1",
         "size-limit": "^8.2.6",
         "transducers-js": "0.4.174",
+        "tstyche": "^1.0.0",
         "typescript": "5.1"
       },
       "engines": {
@@ -13376,6 +13377,29 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "node_modules/tstyche": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-1.0.0.tgz",
+      "integrity": "sha512-iIpktIBuWL0M+KgCO8TIgo+QGS+mD24ll+wAYCFsd8IkA3Lai0ETqGSilHo1PC59+2lf71qJmWShFZwMMH4i1g==",
+      "dev": true,
+      "bin": {
+        "tstyche": "build/bin.js"
+      },
+      "engines": {
+        "node": "^16.14 || 18.x || >=20.x"
+      },
+      "funding": {
+        "url": "https://github.com/tstyche/tstyche?sponsor=1"
+      },
+      "peerDependencies": {
+        "typescript": "4.x || 5.x"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/tsutils": {
       "version": "2.29.0",
       "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
@@ -24148,6 +24172,13 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
       "dev": true
     },
+    "tstyche": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/tstyche/-/tstyche-1.0.0.tgz",
+      "integrity": "sha512-iIpktIBuWL0M+KgCO8TIgo+QGS+mD24ll+wAYCFsd8IkA3Lai0ETqGSilHo1PC59+2lf71qJmWShFZwMMH4i1g==",
+      "dev": true,
+      "requires": {}
+    },
     "tsutils": {
       "version": "2.29.0",
       "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
diff --git a/package.json b/package.json
index eb22adcf9..9f14d03f1 100644
--- a/package.json
+++ b/package.json
@@ -55,7 +55,9 @@
     "npm": ">=7.0.0"
   },
   "scripts": {
-    "test": "run-s format lint type-check build unit-test",
+    "test": "run-s format lint type-check build test:*",
+    "test:unit": "jest",
+    "test:types": "tstyche",
     "format": "npm run lint:format -- --write",
     "lint": "run-s lint:*",
     "lint:format": "prettier --check \"{__tests__,src,type-definitions,website/src,perf,resources}/**/*{.js,.ts,.tsx,.flow,.css}\"",
@@ -69,7 +71,6 @@
     "build:types": "cpy ./type-definitions/immutable.* dist",
     "build:prepare": "./resources/prepare-dist.sh",
     "build:stats": "node ./resources/dist-stats.mjs",
-    "unit-test": "jest",
     "website:build": "cd website && next build && next-sitemap",
     "website:dev": "cd website && next dev",
     "check-git-clean": "./resources/check-git-clean.sh",
@@ -127,6 +128,7 @@
     "rollup": "3.28.1",
     "size-limit": "^8.2.6",
     "transducers-js": "0.4.174",
+    "tstyche": "^1.0.0",
     "typescript": "5.1"
   },
   "size-limit": [
diff --git a/tstyche.config.json b/tstyche.config.json
new file mode 100644
index 000000000..22b2d9784
--- /dev/null
+++ b/tstyche.config.json
@@ -0,0 +1,9 @@
+{
+  "$schema": "https://tstyche.org/schemas/config.json",
+  "testFileMatch": [
+    "**/type-definitions/ts-tests/covariance.ts",
+    "**/type-definitions/ts-tests/deepCopy.ts",
+    "**/type-definitions/ts-tests/empty.ts",
+    "**/type-definitions/ts-tests/es6-collections.ts"
+  ]
+}


Test patch:
diff --git a/type-definitions/ts-tests/covariance.ts b/type-definitions/ts-tests/covariance.ts
index c1bf50ffc..c23cbb541 100644
--- a/type-definitions/ts-tests/covariance.ts
+++ b/type-definitions/ts-tests/covariance.ts
@@ -1,4 +1,13 @@
-import { List, Map, OrderedMap, OrderedSet, Set, Stack } from 'immutable';
+import { expect, test } from 'tstyche';
+import {
+  List,
+  Map,
+  MapOf,
+  OrderedMap,
+  OrderedSet,
+  Set,
+  Stack,
+} from 'immutable';
 
 class A {
   x: number;
@@ -7,6 +16,7 @@ class A {
     this.x = 1;
   }
 }
+
 class B extends A {
   y: string;
 
@@ -15,6 +25,7 @@ class B extends A {
     this.y = 'B';
   }
 }
+
 class C {
   z: string;
 
@@ -23,55 +34,52 @@ class C {
   }
 }
 
-// List covariance
-let listOfB: List<B> = List<B>();
-let listOfA: List<A> = listOfB;
-
-// $ExpectType List<B>
-listOfA = List([new B()]);
-
-// $ExpectError
-let listOfC: List<C> = listOfB;
-
-// Map covariance
-declare let mapOfB: Map<string, B>;
-let mapOfA: Map<string, A> = mapOfB;
-
-// $ExpectType MapOf<{ b: B; }>
-mapOfA = Map({ b: new B() });
-
-// $ExpectError
-let mapOfC: Map<string, C> = mapOfB;
-
-// Set covariance
-declare let setOfB: Set<B>;
-let setOfA: Set<A> = setOfB;
-
-// $ExpectType Set<B>
-setOfA = Set([new B()]);
-// $ExpectError
-let setOfC: Set<C> = setOfB;
-
-// Stack covariance
-declare let stackOfB: Stack<B>;
-let stackOfA: Stack<A> = stackOfB;
-// $ExpectType Stack<B>
-stackOfA = Stack([new B()]);
-// $ExpectError
-let stackOfC: Stack<C> = stackOfB;
-
-// OrderedMap covariance
-declare let orderedMapOfB: OrderedMap<string, B>;
-let orderedMapOfA: OrderedMap<string, A> = orderedMapOfB;
-// $ExpectType OrderedMap<string, B>
-orderedMapOfA = OrderedMap({ b: new B() });
-// $ExpectError
-let orderedMapOfC: OrderedMap<string, C> = orderedMapOfB;
-
-// OrderedSet covariance
-declare let orderedSetOfB: OrderedSet<B>;
-let orderedSetOfA: OrderedSet<A> = orderedSetOfB;
-// $ExpectType OrderedSet<B>
-orderedSetOfA = OrderedSet([new B()]);
-// $ExpectError
-let orderedSetOfC: OrderedSet<C> = orderedSetOfB;
+test('List covariance', () => {
+  expect<List<A>>().type.toBeAssignable(List<B>());
+
+  expect(List([new B()])).type.toEqual<List<B>>();
+
+  expect<List<C>>().type.not.toBeAssignable(List<B>());
+});
+
+test('Map covariance', () => {
+  expect<Map<string, A>>().type.toBeAssignable<Map<string, B>>();
+
+  expect(Map({ b: new B() })).type.toEqual<MapOf<{ b: B }>>();
+
+  expect<Map<string, C>>().type.not.toBeAssignable<Map<string, B>>();
+});
+
+test('Set covariance', () => {
+  expect<Set<A>>().type.toBeAssignable<Set<B>>();
+
+  expect(Set([new B()])).type.toEqual<Set<B>>();
+
+  expect<Set<C>>().type.not.toBeAssignable<Set<B>>();
+});
+
+test('Stack covariance', () => {
+  expect<Stack<A>>().type.toBeAssignable<Stack<B>>();
+
+  expect(Stack([new B()])).type.toEqual<Stack<B>>();
+
+  expect<Stack<C>>().type.not.toBeAssignable<Stack<B>>();
+});
+
+test('OrderedMap covariance', () => {
+  expect<OrderedMap<string, A>>().type.toBeAssignable<OrderedMap<string, B>>();
+
+  expect(OrderedMap({ b: new B() })).type.toEqual<OrderedMap<string, B>>();
+
+  expect<OrderedMap<string, C>>().type.not.toBeAssignable<
+    OrderedMap<string, B>
+  >();
+});
+
+test('OrderedSet covariance', () => {
+  expect<OrderedSet<A>>().type.toBeAssignable<OrderedSet<B>>();
+
+  expect(OrderedSet([new B()])).type.toEqual<OrderedSet<B>>();
+
+  expect<OrderedSet<C>>().type.not.toBeAssignable<OrderedSet<B>>();
+});
diff --git a/type-definitions/ts-tests/deepCopy.ts b/type-definitions/ts-tests/deepCopy.ts
index a3240d3c1..668f00818 100644
--- a/type-definitions/ts-tests/deepCopy.ts
+++ b/type-definitions/ts-tests/deepCopy.ts
@@ -1,122 +1,112 @@
+import { describe, expect, test } from 'tstyche';
 import { List, Map, Record, Set, Seq, DeepCopy, Collection } from 'immutable';
 
-{
-  // Basic types
-
-  // $ExpectType { a: number; b: number; }
-  type Test = DeepCopy<{ a: number; b: number }>;
-}
-
-{
-  // Iterables
-
-  // $ExpectType string[]
-  type Test = DeepCopy<string[]>;
-
-  // $ExpectType number[]
-  type Keyed = DeepCopy<Collection.Indexed<number>>;
-}
-
-{
-  // Immutable first-level types
-
-  // $ExpectType { [x: string]: string; }
-  type StringKey = DeepCopy<Map<string, string>>;
-
-  // should be `{ [x: string]: object; }` but there is an issue with circular references
-  // $ExpectType { [x: string]: unknown; }
-  type ObjectKey = DeepCopy<Map<object, 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<Map<object | number, object>>;
-
-  // $ExpectType string[]
-  type ListDeepCopy = DeepCopy<List<string>>;
-
-  // $ExpectType string[]
-  type SetDeepCopy = DeepCopy<Set<string>>;
-}
-
-{
-  // Keyed
-
-  // $ExpectType { [x: string]: number; }
-  type Keyed = DeepCopy<Collection.Keyed<string, number>>;
-
-  // $ExpectType { [x: string]: number; [x: number]: number; }
-  type KeyedMixed = DeepCopy<Collection.Keyed<string | number, number>>;
-
-  // $ExpectType { [x: string]: number; [x: number]: number; }
-  type KeyedSeqMixed = DeepCopy<Seq.Keyed<string | number, number>>;
-
-  // $ExpectType { [x: string]: number; [x: number]: number; }
-  type MapMixed = DeepCopy<Map<string | number, number>>;
-}
-
-{
-  // 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; }
-  type NestedObject = DeepCopy<{ map: Map<string, string>; list: List<string>; set: Set<string>; }>;
-
-  // should be `{ map: { [x: string]: string; }; }`, but there is an issue with circular references
-  // $ExpectType { map: unknown; }
-  type NestedMap = DeepCopy<Map<'map', Map<string, string>>>;
-}
-
-{
-  // 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<Article>;
-}
-
-{
-  // Circular references #1957
-
-  class Foo1 extends Record<{
-    foo: undefined | Foo1;
-  }>({
-    foo: undefined
-  }) {
-  }
-
-  class Foo2 extends Record<{
-    foo?: Foo2;
-  }>({
-    foo: undefined
-  }) {
-  }
-
-  class Foo3 extends Record<{
-    foo: null | Foo3;
-  }>({
-    foo: null
-  }) {
-  }
-
-  // $ExpectType { foo: unknown; }
-  type DeepFoo1 = DeepCopy<Foo1>;
-
-  // $ExpectType { foo?: unknown; }
-  type DeepFoo2 = DeepCopy<Foo2>;
-
-  // $ExpectType { foo: unknown; }
-  type DeepFoo3 = DeepCopy<Foo3>;
-
-  class FooWithList extends Record<{
-    foos: undefined | List<FooWithList>;
-  }>({
-    foos: undefined
-  }) {
-  }
-
-  // $ExpectType { foos: unknown; }
-  type DeepFooList = DeepCopy<FooWithList>;
-}
+describe('DeepCopy', () => {
+  test('basic types', () => {
+    expect<
+      DeepCopy<{
+        a: number;
+        b: number;
+      }>
+    >().type.toEqual<{
+      a: number;
+      b: number;
+    }>();
+  });
+
+  test('iterables', () => {
+    expect<DeepCopy<string[]>>().type.toEqual<string[]>();
+
+    expect<DeepCopy<Collection.Indexed<number>>>().type.toEqual<number[]>();
+  });
+
+  test('immutable first-level types', () => {
+    expect<DeepCopy<Map<string, string>>>().type.toEqual<{
+      [x: string]: string;
+    }>();
+
+    // should be `{ [x: string]: object }`, but there is an issue with circular references
+    expect<DeepCopy<Map<object, object>>>().type.toEqual<{
+      [x: string]: unknown;
+    }>();
+
+    // should be `{ [x: string]: object; [x: number]: object }`, but there is an issue with circular references
+    expect<DeepCopy<Map<object | number, object>>>().type.toEqual<{
+      [x: string]: unknown;
+      [x: number]: unknown;
+    }>();
+
+    expect<DeepCopy<List<string>>>().type.toEqual<string[]>();
+
+    expect<DeepCopy<Set<string>>>().type.toEqual<string[]>();
+  });
+
+  test('keyed', () => {
+    expect<DeepCopy<Collection.Keyed<string, number>>>().type.toEqual<{
+      [x: string]: number;
+    }>();
+
+    expect<DeepCopy<Collection.Keyed<string | number, number>>>().type.toEqual<{
+      [x: string]: number;
+      [x: number]: number;
+    }>();
+
+    expect<DeepCopy<Seq.Keyed<string | number, number>>>().type.toEqual<{
+      [x: string]: number;
+      [x: number]: number;
+    }>();
+
+    expect<DeepCopy<Map<string | number, number>>>().type.toEqual<{
+      [x: string]: number;
+      [x: number]: number;
+    }>();
+  });
+
+  test('nested', () => {
+    // should be `{ map: { [x: string]: string }; list: string[]; set: string[] }`, but there is an issue with circular references
+    expect<
+      DeepCopy<{
+        map: Map<string, string>;
+        list: List<string>;
+        set: Set<string>;
+      }>
+    >().type.toEqual<{ map: unknown; list: unknown; set: unknown }>();
+
+    // should be `{ map: { [x: string]: string } }`, but there is an issue with circular references
+    expect<DeepCopy<Map<'map', Map<string, string>>>>().type.toEqual<{
+      map: unknown;
+    }>();
+  });
+
+  test('circular references', () => {
+    type Article = Record<{ title: string; tag: Tag }>;
+    type Tag = Record<{ name: string; article: Article }>;
+
+    // should handle circular references here somehow
+    expect<DeepCopy<Article>>().type.toEqual<{ title: string; tag: unknown }>();
+  });
+
+  test('circular references #1957', () => {
+    class Foo1 extends Record<{ foo: undefined | Foo1 }>({
+      foo: undefined,
+    }) {}
+
+    class Foo2 extends Record<{ foo?: Foo2 }>({
+      foo: undefined,
+    }) {}
+
+    class Foo3 extends Record<{ foo: null | Foo3 }>({
+      foo: null,
+    }) {}
+
+    expect<DeepCopy<Foo1>>().type.toEqual<{ foo: unknown }>();
+    expect<DeepCopy<Foo2>>().type.toEqual<{ foo?: unknown }>();
+    expect<DeepCopy<Foo3>>().type.toEqual<{ foo: unknown }>();
+
+    class FooWithList extends Record<{ foo: undefined | List<FooWithList> }>({
+      foo: undefined,
+    }) {}
+
+    expect<DeepCopy<FooWithList>>().type.toEqual<{ foo: unknown }>();
+  });
+});
diff --git a/type-definitions/ts-tests/empty.ts b/type-definitions/ts-tests/empty.ts
index 289da3fab..f2065e147 100644
--- a/type-definitions/ts-tests/empty.ts
+++ b/type-definitions/ts-tests/empty.ts
@@ -1,57 +1,44 @@
+import { expect, test } from 'tstyche';
 import { Seq, Collection } from 'immutable';
 
-{
-  // Typed empty seqs
+test('typed empty Seq', () => {
+  expect(Seq()).type.toEqual<Seq<unknown, unknown>>();
 
-  // $ExpectType Seq<unknown, unknown>
-  Seq();
+  expect(Seq<number, string>()).type.toEqual<Seq<number, string>>();
 
-  // $ExpectType Seq<number, string>
-  Seq<number, string>();
+  expect(Seq.Indexed()).type.toEqual<Seq.Indexed<unknown>>();
 
-  // $ExpectType Indexed<unknown>
-  Seq.Indexed();
+  expect(Seq.Indexed<string>()).type.toEqual<Seq.Indexed<string>>();
 
-  // $ExpectType Indexed<string>
-  Seq.Indexed<string>();
+  expect(Seq.Keyed()).type.toEqual<Seq.Keyed<unknown, unknown>>();
 
-  // $ExpectType Keyed<unknown, unknown>
-  Seq.Keyed();
+  expect(Seq.Keyed<number, string>()).type.toEqual<Seq.Keyed<number, string>>();
 
-  // $ExpectType Keyed<number, string>
-  Seq.Keyed<number, string>();
+  expect(Seq.Set()).type.toEqual<Seq.Set<unknown>>();
 
-  // $ExpectType Set<unknown>
-  Seq.Set();
+  expect(Seq.Set<string>()).type.toEqual<Seq.Set<string>>();
+});
 
-  // $ExpectType Set<string>
-  Seq.Set<string>();
-}
+test('typed empty Collection', () => {
+  expect(Collection()).type.toEqual<Collection<unknown, unknown>>();
 
-{
-  // Typed empty collection
+  expect(Collection<number, string>()).type.toEqual<
+    Collection<number, string>
+  >();
 
-  // $ExpectType Collection<unknown, unknown>
-  Collection();
+  expect(Collection.Indexed()).type.toEqual<Collection.Indexed<unknown>>();
 
-  // $ExpectType Collection<number, string>
-  Collection<number, string>();
+  expect(Collection.Indexed<string>()).type.toEqual<
+    Collection.Indexed<string>
+  >();
 
-  // $ExpectType Indexed<unknown>
-  Collection.Indexed();
+  expect(Collection.Keyed()).type.toEqual<Collection.Keyed<unknown, unknown>>();
 
-  // $ExpectType Indexed<string>
-  Collection.Indexed<string>();
+  expect(Collection.Keyed<number, string>()).type.toEqual<
+    Collection.Keyed<number, string>
+  >();
 
-  // $ExpectType Keyed<unknown, unknown>
-  Collection.Keyed();
+  expect(Collection.Set()).type.toEqual<Collection.Set<unknown>>();
 
-  // $ExpectType Keyed<number, string>
-  Collection.Keyed<number, string>();
-
-  // $ExpectType Set<unknown>
-  Collection.Set();
-
-  // $ExpectType Set<string>
-  Collection.Set<string>();
-}
+  expect(Collection.Set<string>()).type.toEqual<Collection.Set<string>>();
+});
diff --git a/type-definitions/ts-tests/es6-collections.ts b/type-definitions/ts-tests/es6-collections.ts
index 738c435c6..9fd6eb46b 100644
--- a/type-definitions/ts-tests/es6-collections.ts
+++ b/type-definitions/ts-tests/es6-collections.ts
@@ -1,18 +1,23 @@
-import {
-  Map as ImmutableMap,
-  Set as ImmutableSet,
-} from 'immutable';
+import { expect, test } from 'tstyche';
+import { Map as ImmutableMap, Set as ImmutableSet } from 'immutable';
 
-// Immutable.js collections
-const mapImmutable: ImmutableMap<string, number> = ImmutableMap<string, number>();
-const setImmutable: ImmutableSet<string> = ImmutableSet<string>();
+test('immutable.js collections', () => {
+  const mapImmutable: ImmutableMap<string, number> = ImmutableMap<
+    string,
+    number
+  >();
+  const setImmutable: ImmutableSet<string> = ImmutableSet<string>();
 
-// $ExpectType Map<string, number>
-mapImmutable.delete('foo');
+  expect(mapImmutable.delete('foo')).type.toEqual<
+    ImmutableMap<string, number>
+  >();
+  expect(setImmutable.delete('bar')).type.toEqual<ImmutableSet<string>>();
+});
 
-// ES6 collections
-const mapES6: Map<string, number> = new Map<string, number>();
-const setES6: Set<string> = new Set<string>();
+test('ES6 collections', () => {
+  const mapES6: Map<string, number> = new Map<string, number>();
+  const setES6: Set<string> = new Set<string>();
 
-// $ExpectType boolean
-mapES6.delete('foo');
+  expect(mapES6.delete('foo')).type.toEqual<boolean>();
+  expect(setES6.delete('bar')).type.toEqual<boolean>();
+});
diff --git a/type-definitions/ts-tests/tslint.json b/type-definitions/ts-tests/tslint.json
index 674e90cb8..c8ae42edc 100644
--- a/type-definitions/ts-tests/tslint.json
+++ b/type-definitions/ts-tests/tslint.json
@@ -1,5 +1,8 @@
 {
   "extends": "dtslint/dtslint.json",
+  "linterOptions": {
+    "exclude": ["covariance.ts", "deepCopy.ts", "empty.ts", "es6-collections.ts"]
+  },
   "rules": {
     "no-var": false,
     "prefer-const": false,