tstyche 6.0.0 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -100,4 +100,4 @@ Visit [tstyche.org](https://tstyche.org) to view the full documentation.
100
100
  [coverage-badge]: https://badgen.net/codacy/coverage/a581ca5c323a455886b7bdd9623c4ec8
101
101
  [coverage-url]: https://app.codacy.com/gh/tstyche/tstyche/coverage/dashboard
102
102
  [starter-badge]: https://developer.stackblitz.com/img/open_in_stackblitz.svg
103
- [starter-url]: https://stackblitz.com/fork/github/tstyche/tstyche-starter?file=README.md&title=TSTyche%20Starter%20Project&view=editor
103
+ [starter-url]: https://tstyche.org/new
package/dist/tstyche.js CHANGED
@@ -4587,9 +4587,6 @@ function getTargetSymbol(symbol, compiler) {
4587
4587
  function isCheckFlagSet(symbol, flag, compiler) {
4588
4588
  return !!(symbol.flags & compiler.SymbolFlags.Transient && symbol.links.checkFlags & flag);
4589
4589
  }
4590
- function isSymbolFromDefaultLibrary(symbol, program) {
4591
- return !!symbol.declarations?.every((declaration) => program.isSourceFileDefaultLibrary(declaration.getSourceFile()));
4592
- }
4593
4590
 
4594
4591
  function getParameterFactsFromTuple(type, position, compiler) {
4595
4592
  return {
@@ -4659,31 +4656,15 @@ function isReadonlyProperty(symbol, compiler) {
4659
4656
  (symbol.flags & compiler.SymbolFlags.Accessor && !(symbol.flags & compiler.SymbolFlags.SetAccessor)));
4660
4657
  }
4661
4658
 
4662
- class SeenService {
4663
- #cache = new Map();
4664
- memoized(a, b, compare) {
4665
- const key = [a.id, b.id].sort().join(":");
4666
- const result = this.#cache.get(key);
4667
- if (result !== undefined) {
4668
- return result !== 2;
4669
- }
4670
- this.#cache.set(key, 0);
4671
- const isSame = compare();
4672
- this.#cache.set(key, isSame ? 1 : 2);
4673
- return isSame;
4674
- }
4675
- }
4676
-
4677
4659
  class Structure {
4678
4660
  #compiler;
4679
4661
  #compilerOptions;
4680
- #program;
4681
- #seen = new SeenService();
4682
4662
  #typeChecker;
4663
+ #deduplicateCache = new WeakMap();
4664
+ #memoizeCache = new Map();
4683
4665
  constructor(compiler, program) {
4684
4666
  this.#compiler = compiler;
4685
4667
  this.#compilerOptions = program.getCompilerOptions();
4686
- this.#program = program;
4687
4668
  this.#typeChecker = program.getTypeChecker();
4688
4669
  }
4689
4670
  #compareMaybeNullish(a, b) {
@@ -4717,7 +4698,7 @@ class Structure {
4717
4698
  return false;
4718
4699
  }
4719
4700
  if ((a.flags & b.flags) | this.#compiler.TypeFlags.StructuredType) {
4720
- return this.#seen.memoized(a, b, () => this.compareStructuredTypes(a, b));
4701
+ return this.#memoize(a, b, () => this.compareStructuredTypes(a, b));
4721
4702
  }
4722
4703
  return false;
4723
4704
  }
@@ -4729,7 +4710,7 @@ class Structure {
4729
4710
  }
4730
4711
  if ((a.flags | b.flags) & this.#compiler.TypeFlags.Object) {
4731
4712
  if (a.flags & b.flags & this.#compiler.TypeFlags.Object) {
4732
- return this.#seen.memoized(a, b, () => this.compareObjects(a, b));
4713
+ return this.#memoize(a, b, () => this.compareObjects(a, b));
4733
4714
  }
4734
4715
  return false;
4735
4716
  }
@@ -4778,22 +4759,25 @@ class Structure {
4778
4759
  return false;
4779
4760
  }
4780
4761
  compareIntersections(a, b) {
4781
- if (a.types.length !== b.types.length) {
4762
+ const aTypes = this.#deduplicate(a);
4763
+ const bTypes = this.#deduplicate(b);
4764
+ if (aTypes.length !== bTypes.length) {
4782
4765
  return false;
4783
4766
  }
4784
- return a.types.every((aType, i) => this.compare(aType, b.types[i]));
4767
+ return aTypes.every((aType, i) => this.compare(aType, bTypes[i]));
4785
4768
  }
4786
4769
  compareUnions(a, b) {
4787
- if (a.types.length !== b.types.length) {
4770
+ const aTypes = this.#deduplicate(a);
4771
+ const bTypes = this.#deduplicate(b);
4772
+ if (aTypes.length !== bTypes.length) {
4788
4773
  return false;
4789
4774
  }
4790
- return a.types.every((aType) => b.types.some((bType) => this.compare(aType, bType)));
4775
+ return aTypes.every((aType) => bTypes.some((bType) => this.compare(aType, bType)));
4791
4776
  }
4792
4777
  compareObjects(a, b) {
4793
4778
  if (a.objectFlags & b.objectFlags & this.#compiler.ObjectFlags.Reference) {
4794
- const isSame = this.compareTypeReferences(a, b);
4795
- if (isSame != null) {
4796
- return isSame;
4779
+ if (!((a.objectFlags | b.objectFlags) & this.#compiler.ObjectFlags.ClassOrInterface)) {
4780
+ return this.compareTypeReferences(a, b);
4797
4781
  }
4798
4782
  }
4799
4783
  return this.compareStructuredTypes(a, b);
@@ -4805,21 +4789,20 @@ class Structure {
4805
4789
  }
4806
4790
  return false;
4807
4791
  }
4808
- if ((a.objectFlags | b.objectFlags) & this.#compiler.ObjectFlags.Class) {
4792
+ if (!this.compare(a.target, b.target)) {
4809
4793
  return this.compareStructuredTypes(a, b);
4810
4794
  }
4811
- if (a.symbol !== b.symbol) {
4812
- if (isSymbolFromDefaultLibrary(a.symbol, this.#program) || isSymbolFromDefaultLibrary(b.symbol, this.#program)) {
4813
- return false;
4814
- }
4815
- return;
4816
- }
4817
4795
  const aTypeArguments = this.#typeChecker.getTypeArguments(a);
4818
4796
  const bTypeArguments = this.#typeChecker.getTypeArguments(b);
4819
4797
  if (aTypeArguments.length !== bTypeArguments.length) {
4820
4798
  return false;
4821
4799
  }
4822
- return aTypeArguments.every((type, i) => this.compare(type, bTypeArguments[i]));
4800
+ for (let i = 0; i < aTypeArguments.length; i++) {
4801
+ if (!this.compare(aTypeArguments[i], bTypeArguments[i])) {
4802
+ return false;
4803
+ }
4804
+ }
4805
+ return true;
4823
4806
  }
4824
4807
  compareTuples(a, b) {
4825
4808
  if (a.target.readonly !== b.target.readonly) {
@@ -5044,14 +5027,39 @@ class Structure {
5044
5027
  }
5045
5028
  return true;
5046
5029
  }
5030
+ #deduplicate(target) {
5031
+ let result = this.#deduplicateCache.get(target);
5032
+ if (result) {
5033
+ return result;
5034
+ }
5035
+ result = target.types.slice(0, 1);
5036
+ for (let i = 1; i < target.types.length; i++) {
5037
+ if (!result.some((existing) => this.compare(existing, target.types[i]))) {
5038
+ result.push(target.types[i]);
5039
+ }
5040
+ }
5041
+ this.#deduplicateCache.set(target, result);
5042
+ return result;
5043
+ }
5044
+ #memoize(a, b, compare) {
5045
+ const key = [a.id, b.id].sort().join(":");
5046
+ const result = this.#memoizeCache.get(key);
5047
+ if (result !== undefined) {
5048
+ return result !== 2;
5049
+ }
5050
+ this.#memoizeCache.set(key, 0);
5051
+ const isSame = compare();
5052
+ this.#memoizeCache.set(key, isSame ? 1 : 2);
5053
+ return isSame;
5054
+ }
5047
5055
  #normalize(type) {
5048
5056
  if (type.flags & this.#compiler.TypeFlags.Freshable && type.freshType === type) {
5049
5057
  return type.regularType;
5050
5058
  }
5051
5059
  if (type.flags & this.#compiler.TypeFlags.UnionOrIntersection) {
5052
- const candidateType = type.types[0];
5053
- if (type.types.every((t) => this.compare(t, candidateType))) {
5054
- return candidateType;
5060
+ const parts = this.#deduplicate(type);
5061
+ if (parts.length === 1) {
5062
+ return parts.at(0);
5055
5063
  }
5056
5064
  }
5057
5065
  return type;
@@ -5912,7 +5920,7 @@ class FileRunner {
5912
5920
  class Runner {
5913
5921
  #eventEmitter = new EventEmitter();
5914
5922
  #resolvedConfig;
5915
- static version = "6.0.0";
5923
+ static version = "6.0.2";
5916
5924
  constructor(resolvedConfig) {
5917
5925
  this.#resolvedConfig = resolvedConfig;
5918
5926
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",