tstyche 6.0.0-beta.0 → 6.0.0-beta.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.
@@ -158,7 +158,6 @@ interface ConfigFileOptions {
158
158
  checkSuppressedErrors?: boolean;
159
159
  failFast?: boolean;
160
160
  fixtureFileMatch?: Array<string>;
161
- legacyToBe?: boolean;
162
161
  plugins?: Array<string>;
163
162
  rejectAnyType?: boolean;
164
163
  rejectNeverType?: boolean;
@@ -720,9 +719,7 @@ declare class Store {
720
719
  #private;
721
720
  static manifest: Manifest | undefined;
722
721
  static fetch(tag: string): Promise<void>;
723
- static load(tag: string, options?: {
724
- notPatched?: boolean;
725
- }): Promise<typeof ts | undefined>;
722
+ static load(tag: string): Promise<typeof ts | undefined>;
726
723
  static open(): Promise<void>;
727
724
  static prune(): Promise<void>;
728
725
  static update(): Promise<void>;
package/build/tstyche.js CHANGED
@@ -1,11 +1,9 @@
1
1
  import { writeFileSync, rmSync, existsSync, watch } from 'node:fs';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
- import { fileURLToPath, pathToFileURL } from 'node:url';
4
+ import { pathToFileURL, fileURLToPath } from 'node:url';
5
5
  import os from 'node:os';
6
6
  import process from 'node:process';
7
- import { createRequire } from 'node:module';
8
- import vm from 'node:vm';
9
7
 
10
8
  class EventEmitter {
11
9
  static instanceCount = 0;
@@ -397,9 +395,9 @@ class ConfigDiagnosticText {
397
395
  }
398
396
  static rangeUsage() {
399
397
  return [
400
- "A range must be specified using an operator and a minor version: '>=5.5'.",
401
- "To set an upper bound, use the intersection of two ranges: '>=5.0 <5.3'.",
402
- "Use the '||' operator to join ranges into a union: '>=5.2 <=5.3 || 5.4.2 || >5.5'.",
398
+ "A range must be specified using an operator and a minor version: '>=5.8'.",
399
+ "To set an upper bound, use the intersection of two ranges: '>=5.4 <5.6'.",
400
+ "Use the '||' operator to join ranges into a union: '>=5.4 <5.6 || 5.6.2 || >=5.8'.",
403
401
  ];
404
402
  }
405
403
  static seen(element) {
@@ -731,7 +729,7 @@ class ManifestService {
731
729
  const versions = [];
732
730
  const packageMetadata = (await response.json());
733
731
  for (const [tag, meta] of Object.entries(packageMetadata.versions)) {
734
- if (!tag.includes("-") && Version.isSatisfiedWith(tag, "5.0.2")) {
732
+ if (!tag.includes("-") && Version.isSatisfiedWith(tag, "5.4.2")) {
735
733
  versions.push(tag);
736
734
  packages[tag] = { integrity: meta.dist.integrity, tarball: meta.dist.tarball };
737
735
  }
@@ -896,7 +894,6 @@ class PackageService {
896
894
  }
897
895
 
898
896
  class Store {
899
- static #compilerInstanceCache = new Map();
900
897
  static #fetcher;
901
898
  static #lockService;
902
899
  static manifest;
@@ -924,14 +921,10 @@ class Store {
924
921
  }
925
922
  await Store.#packageService.ensure(version, Store.manifest);
926
923
  }
927
- static async load(tag, options) {
928
- let compilerInstance = Store.#compilerInstanceCache.get(tag);
929
- if (compilerInstance != null) {
930
- return compilerInstance;
931
- }
932
- let modulePath;
924
+ static async load(tag) {
925
+ let resolvedModule;
933
926
  if (tag === "*" && environmentOptions.typescriptModule != null) {
934
- modulePath = fileURLToPath(environmentOptions.typescriptModule);
927
+ resolvedModule = environmentOptions.typescriptModule;
935
928
  }
936
929
  else {
937
930
  await Store.open();
@@ -940,40 +933,15 @@ class Store {
940
933
  Store.#onDiagnostics(Diagnostic.error(StoreDiagnosticText.cannotAddTypeScriptPackage(tag)));
941
934
  return;
942
935
  }
943
- compilerInstance = Store.#compilerInstanceCache.get(version);
944
- if (compilerInstance != null) {
945
- return compilerInstance;
946
- }
947
936
  const packagePath = await Store.#packageService.ensure(version, Store.manifest);
948
937
  if (packagePath != null) {
949
- modulePath = Path.join(packagePath, "lib", "typescript.js");
938
+ resolvedModule = pathToFileURL(`${packagePath}/lib/typescript.js`).toString();
950
939
  }
951
940
  }
952
- if (modulePath != null) {
953
- const packageConfigText = await fs.readFile(Path.resolve(modulePath, "../../package.json"), { encoding: "utf8" });
954
- const { version: packageVersion } = JSON.parse(packageConfigText);
955
- if (!Version.isSatisfiedWith(packageVersion, "5.3")) {
956
- modulePath = Path.resolve(modulePath, "../tsserverlibrary.js");
957
- }
958
- if (options?.notPatched) {
959
- const moduleSpecifier = pathToFileURL(modulePath).toString();
960
- compilerInstance = (await import(moduleSpecifier)).default;
961
- }
962
- else {
963
- compilerInstance = await Store.#loadPatchedModule(modulePath);
964
- }
965
- Store.#compilerInstanceCache.set(tag, compilerInstance);
966
- Store.#compilerInstanceCache.set(compilerInstance.version, compilerInstance);
941
+ if (resolvedModule != null) {
942
+ return (await import(resolvedModule)).default;
967
943
  }
968
- return compilerInstance;
969
- }
970
- static async #loadPatchedModule(modulePath) {
971
- const sourceText = await fs.readFile(modulePath, { encoding: "utf8" });
972
- const compiledWrapper = vm.compileFunction(sourceText.replace("return checker;", "return { ...checker, isTypeIdenticalTo };"), ["exports", "require", "module", "__filename", "__dirname"], { filename: modulePath });
973
- const exports$1 = {};
974
- const module = { exports: exports$1 };
975
- compiledWrapper(exports$1, createRequire(modulePath), module, modulePath, Path.dirname(modulePath));
976
- return module.exports;
944
+ return;
977
945
  }
978
946
  static #onDiagnostics(diagnostic) {
979
947
  EventEmitter.dispatch(["store:error", { diagnostics: [diagnostic] }]);
@@ -1107,12 +1075,6 @@ class Options {
1107
1075
  group: 2,
1108
1076
  name: "help",
1109
1077
  },
1110
- {
1111
- brand: "boolean",
1112
- description: "Use the patch-based implementation of the '.toBe()' matcher.",
1113
- group: 4,
1114
- name: "legacyToBe",
1115
- },
1116
1078
  {
1117
1079
  brand: "true",
1118
1080
  description: "Print the list of supported versions of the 'typescript' package and exit.",
@@ -1603,7 +1565,6 @@ const defaultOptions = {
1603
1565
  checkSuppressedErrors: true,
1604
1566
  failFast: false,
1605
1567
  fixtureFileMatch: ["**/__fixtures__/*.{ts,tsx}", "**/fixtures/*.{ts,tsx}"],
1606
- legacyToBe: false,
1607
1568
  plugins: [],
1608
1569
  rejectAnyType: true,
1609
1570
  rejectNeverType: true,
@@ -2432,7 +2393,7 @@ function CommandLineUsageText() {
2432
2393
  const usage = [
2433
2394
  ["tstyche", "Run all tests."],
2434
2395
  ["tstyche query-params", "Only run the matching test file."],
2435
- ["tstyche --target '5.3 || 5.5.2 || >=5.7'", "Test against specific versions of TypeScript."],
2396
+ ["tstyche --target '5.4 || 5.6.2 || >=5.8'", "Test against specific versions of TypeScript."],
2436
2397
  ];
2437
2398
  const usageText = usage.map(([commandText, descriptionText]) => (jsx(Line, { children: [jsx(CommandText, { text: commandText }), jsx(OptionDescriptionText, { text: descriptionText })] })));
2438
2399
  return jsx(Text, { children: usageText });
@@ -4363,29 +4324,6 @@ class ExpectDiagnosticText {
4363
4324
  }
4364
4325
  }
4365
4326
 
4366
- class RelationMatcherBase {
4367
- explain(matchWorker, sourceNode, targetNode) {
4368
- const sourceTypeText = matchWorker.getTypeText(sourceNode);
4369
- const targetTypeText = matchWorker.getTypeText(targetNode);
4370
- const text = matchWorker.assertionNode.isNot
4371
- ? this.explainText(sourceTypeText, targetTypeText)
4372
- : this.explainNotText(sourceTypeText, targetTypeText);
4373
- const origin = DiagnosticOrigin.fromNode(targetNode, matchWorker.assertionNode);
4374
- return [Diagnostic.error(text, origin)];
4375
- }
4376
- }
4377
-
4378
- class LegacyToBe extends RelationMatcherBase {
4379
- explainText = ExpectDiagnosticText.isTheSame;
4380
- explainNotText = ExpectDiagnosticText.isNotTheSame;
4381
- match(matchWorker, sourceNode, targetNode) {
4382
- return {
4383
- explain: () => this.explain(matchWorker, sourceNode, targetNode),
4384
- isMatch: matchWorker.checkIsIdenticalTo(sourceNode, targetNode),
4385
- };
4386
- }
4387
- }
4388
-
4389
4327
  class MatchWorker {
4390
4328
  assertionNode;
4391
4329
  #compiler;
@@ -4397,25 +4335,15 @@ class MatchWorker {
4397
4335
  this.assertionNode = assertionNode;
4398
4336
  }
4399
4337
  checkIsAssignableTo(sourceNode, targetNode) {
4400
- return this.#checkIsRelatedTo(sourceNode, targetNode, "assignable");
4338
+ return this.#checkIsRelatedTo(sourceNode, targetNode);
4401
4339
  }
4402
4340
  checkIsAssignableWith(sourceNode, targetNode) {
4403
- return this.#checkIsRelatedTo(targetNode, sourceNode, "assignable");
4404
- }
4405
- checkIsIdenticalTo(sourceNode, targetNode) {
4406
- return (this.#checkIsRelatedTo(sourceNode, targetNode, "identical") &&
4407
- this.checkIsAssignableTo(sourceNode, targetNode) &&
4408
- this.checkIsAssignableWith(sourceNode, targetNode));
4341
+ return this.#checkIsRelatedTo(targetNode, sourceNode);
4409
4342
  }
4410
- #checkIsRelatedTo(sourceNode, targetNode, relation) {
4411
- const sourceType = relation === "identical" ? this.#simplifyType(this.getType(sourceNode)) : this.getType(sourceNode);
4412
- const targetType = relation === "identical" ? this.#simplifyType(this.getType(targetNode)) : this.getType(targetNode);
4413
- switch (relation) {
4414
- case "assignable":
4415
- return this.typeChecker.isTypeAssignableTo(sourceType, targetType);
4416
- case "identical":
4417
- return this.typeChecker.isTypeIdenticalTo(sourceType, targetType);
4418
- }
4343
+ #checkIsRelatedTo(sourceNode, targetNode) {
4344
+ const sourceType = this.getType(sourceNode);
4345
+ const targetType = this.getType(targetNode);
4346
+ return this.typeChecker.isTypeAssignableTo(sourceType, targetType);
4419
4347
  }
4420
4348
  extendsObjectType(type) {
4421
4349
  const nonPrimitiveType = "getNonPrimitiveType" in this.typeChecker
@@ -4458,21 +4386,12 @@ class MatchWorker {
4458
4386
  }
4459
4387
  return DiagnosticOrigin.fromNode(enclosingNode, this.assertionNode);
4460
4388
  }
4461
- #simplifyType(type) {
4462
- if (type.isUnionOrIntersection()) {
4463
- const candidateType = this.#simplifyType(type.types[0]);
4464
- if (type.types.every((type) => this.typeChecker.isTypeIdenticalTo(this.#simplifyType(type), candidateType))) {
4465
- return candidateType;
4466
- }
4467
- }
4468
- return type;
4469
- }
4470
4389
  }
4471
4390
 
4472
4391
  function isStringOrNumberLiteralType(compiler, type) {
4473
4392
  return !!(type.flags & compiler.TypeFlags.StringOrNumberLiteral);
4474
4393
  }
4475
- function isUnionType$1(compiler, type) {
4394
+ function isUnionType(compiler, type) {
4476
4395
  return !!(type.flags & compiler.TypeFlags.Union);
4477
4396
  }
4478
4397
  function isUniqueSymbolType(compiler, type) {
@@ -4541,7 +4460,7 @@ class ToAcceptProps {
4541
4460
  }
4542
4461
  return true;
4543
4462
  };
4544
- if (sourceType != null && isUnionType$1(this.#compiler, sourceType)) {
4463
+ if (sourceType != null && isUnionType(this.#compiler, sourceType)) {
4545
4464
  return sourceType.types.some((sourceType) => check(sourceType, targetType));
4546
4465
  }
4547
4466
  return check(sourceType, targetType);
@@ -4609,7 +4528,7 @@ class ToAcceptProps {
4609
4528
  }
4610
4529
  return { diagnostics, isMatch: false };
4611
4530
  };
4612
- if (sourceType != null && isUnionType$1(this.#compiler, sourceType)) {
4531
+ if (sourceType != null && isUnionType(this.#compiler, sourceType)) {
4613
4532
  let accumulator = [];
4614
4533
  const isMatch = sourceType.types.some((sourceType) => {
4615
4534
  const text = matchWorker.assertionNode.isNot
@@ -4666,43 +4585,38 @@ class ToAcceptProps {
4666
4585
  function ensureArray(input) {
4667
4586
  return input ?? [];
4668
4587
  }
4669
- function length(array) {
4670
- return array?.length ?? 0;
4671
- }
4672
-
4673
- function isClass(type, compiler) {
4674
- return !!(type.objectFlags & compiler.ObjectFlags.Class);
4675
- }
4676
- function isConditionalType(type, compiler) {
4677
- return !!(type.flags & compiler.TypeFlags.Conditional);
4678
- }
4679
- function isFreshLiteralType(type, compiler) {
4680
- return !!(type.flags & compiler.TypeFlags.Freshable) && type.freshType === type;
4681
- }
4682
- function isIntersectionType(type, compiler) {
4683
- return !!(type.flags & compiler.TypeFlags.Intersection);
4684
- }
4685
- function isNoInferType(type, compiler) {
4686
- return !!(type.flags & compiler.TypeFlags.Substitution &&
4687
- type.constraint.flags & compiler.TypeFlags.Unknown);
4588
+ function getIndexSignatures(type, compiler, typeChecker) {
4589
+ if (type.flags & compiler.TypeFlags.Intersection) {
4590
+ return type.types.flatMap((type) => getIndexSignatures(type, compiler, typeChecker));
4591
+ }
4592
+ return typeChecker.getIndexInfosOfType(type);
4688
4593
  }
4689
- function isObjectType(type, compiler) {
4690
- return !!(type.flags & compiler.TypeFlags.Object);
4594
+ function getSignatures(type, kind, compiler, typeChecker) {
4595
+ if (type.flags & compiler.TypeFlags.Intersection) {
4596
+ return type.types.flatMap((type) => getSignatures(type, kind, compiler, typeChecker));
4597
+ }
4598
+ return typeChecker.getSignaturesOfType(type, kind);
4691
4599
  }
4692
- function isUnionType(type, compiler) {
4693
- return !!(type.flags & compiler.TypeFlags.Union);
4600
+ function getTypeParameterModifiers(typeParameter, compiler) {
4601
+ if (!typeParameter.symbol.declarations) {
4602
+ return compiler.ModifierFlags.None;
4603
+ }
4604
+ return (typeParameter.symbol.declarations.reduce((modifiers, declaration) => modifiers | compiler.getEffectiveModifierFlags(declaration), compiler.ModifierFlags.None) &
4605
+ (compiler.ModifierFlags.In | compiler.ModifierFlags.Out | compiler.ModifierFlags.Const));
4694
4606
  }
4695
- function isTupleType(type, compiler) {
4696
- return !!(type.objectFlags & compiler.ObjectFlags.Tuple);
4607
+ function getTargetSymbol(symbol, compiler) {
4608
+ return isCheckFlagSet(symbol, compiler.CheckFlags.Instantiated, compiler)
4609
+ ? symbol.links.target
4610
+ : symbol;
4697
4611
  }
4698
- function isTupleTypeReference(type, compiler) {
4699
- return isObjectType(type, compiler) && isTypeReference(type, compiler) && isTupleType(type.target, compiler);
4612
+ function isCheckFlagSet(symbol, flag, compiler) {
4613
+ return !!(symbol.flags & compiler.SymbolFlags.Transient && symbol.links.checkFlags & flag);
4700
4614
  }
4701
- function isTypeParameter(type, compiler) {
4702
- return !!(type.flags & compiler.TypeFlags.TypeParameter);
4615
+ function isSymbolFromDefaultLibrary(symbol, program) {
4616
+ return !!symbol.declarations?.every((declaration) => program.isSourceFileDefaultLibrary(declaration.getSourceFile()));
4703
4617
  }
4704
- function isTypeReference(type, compiler) {
4705
- return !!(type.objectFlags & compiler.ObjectFlags.Reference);
4618
+ function length(array) {
4619
+ return array?.length ?? 0;
4706
4620
  }
4707
4621
 
4708
4622
  function getParameterFactsFromTuple(type, position, compiler) {
@@ -4712,41 +4626,30 @@ function getParameterFactsFromTuple(type, position, compiler) {
4712
4626
  getType: (typeChecker) => typeChecker.getTypeArguments(type)[position],
4713
4627
  };
4714
4628
  }
4715
- function getParameterFacts(signature, position, compiler, typeChecker) {
4716
- if (position >= signature.parameters.length - 1 && compiler.hasRestParameter(signature.getDeclaration())) {
4629
+ function getParameterFacts(signature, parameterIndex, compiler, typeChecker) {
4630
+ if (parameterIndex >= signature.parameters.length - 1 && compiler.hasRestParameter(signature.getDeclaration())) {
4717
4631
  const restType = typeChecker.getTypeOfSymbol(signature.parameters.at(-1));
4718
- if (isTupleTypeReference(restType, compiler)) {
4632
+ if (typeChecker.isTupleType(restType)) {
4719
4633
  const fixedLength = signature.parameters.length - 1;
4720
- return getParameterFactsFromTuple(restType, position - fixedLength, compiler);
4634
+ return getParameterFactsFromTuple(restType, parameterIndex - fixedLength, compiler);
4721
4635
  }
4722
4636
  }
4723
- const parameter = signature.parameters[position];
4724
- const isRest = isRestParameter(parameter, compiler);
4637
+ const parameter = signature.parameters[parameterIndex];
4725
4638
  return {
4726
4639
  isOptional: isOptionalParameter(parameter, compiler),
4727
- isRest,
4728
- getType: (typeChecker) => getParameterType(parameter, signature, isRest, compiler, typeChecker),
4640
+ isRest: isRestParameter(parameter, compiler),
4641
+ getType: (typeChecker) => typeChecker.getParameterType(signature, parameterIndex),
4729
4642
  };
4730
4643
  }
4731
- function getParameterType(parameter, signature, isRest, compiler, typeChecker) {
4732
- const type = typeChecker.getTypeOfSymbolAtLocation(parameter, signature.declaration);
4733
- if (isRest && isObjectType(type, compiler) && isTypeReference(type, compiler)) {
4734
- return typeChecker.getTypeArguments(type).at(0);
4735
- }
4736
- return type;
4737
- }
4738
4644
  function getParameterCount(signature, compiler, typeChecker) {
4739
- if (hasRestParameter(signature, compiler)) {
4645
+ if (signature.declaration != null && compiler.hasRestParameter(signature.declaration)) {
4740
4646
  const restType = typeChecker.getTypeOfSymbol(signature.parameters.at(-1));
4741
- if (isTupleTypeReference(restType, compiler)) {
4647
+ if (typeChecker.isTupleType(restType)) {
4742
4648
  return signature.parameters.length + typeChecker.getTypeArguments(restType).length - 1;
4743
4649
  }
4744
4650
  }
4745
4651
  return signature.parameters.length;
4746
4652
  }
4747
- function hasRestParameter(signature, compiler) {
4748
- return signature.declaration != null && compiler.hasRestParameter(signature.declaration);
4749
- }
4750
4653
  function isOptionalParameter(symbol, compiler) {
4751
4654
  return (symbol.valueDeclaration != null &&
4752
4655
  compiler.isParameter(symbol.valueDeclaration) &&
@@ -4758,29 +4661,18 @@ function isRestParameter(symbol, compiler) {
4758
4661
  symbol.valueDeclaration.dotDotDotToken != null);
4759
4662
  }
4760
4663
 
4761
- function getTargetSymbol(symbol, compiler) {
4762
- return isCheckFlagSet(symbol, compiler.CheckFlags.Instantiated, compiler)
4763
- ? symbol.links.target
4764
- : symbol;
4765
- }
4766
- function isCheckFlagSet(symbol, flag, compiler) {
4767
- return !!(symbol.flags & compiler.SymbolFlags.Transient && symbol.links.checkFlags & flag);
4768
- }
4769
- function isSymbolFromDefaultLibrary(symbol, program) {
4770
- if (!symbol.declarations) {
4771
- return false;
4772
- }
4773
- return symbol.declarations.every((declaration) => program.isSourceFileDefaultLibrary(declaration.getSourceFile()));
4774
- }
4775
-
4776
4664
  function getPropertyType(symbol, compiler, compilerOptions, typeChecker) {
4777
4665
  const type = typeChecker.getTypeOfSymbol(symbol);
4778
4666
  if (compilerOptions.exactOptionalPropertyTypes && isOptionalProperty(symbol, compiler)) {
4779
- if (isUnionType(type, compiler)) {
4780
- type.types = type.types.filter((type) => !("debugIntrinsicName" in type && type.debugIntrinsicName === "missing"));
4781
- if (type.types.length === 1) {
4782
- return type.types.at(0);
4667
+ if (type.flags & compiler.TypeFlags.Union) {
4668
+ const filteredType = type.types.filter((type) => !("debugIntrinsicName" in type && type.debugIntrinsicName === "missing"));
4669
+ if (filteredType.length === type.types.length) {
4670
+ return type;
4783
4671
  }
4672
+ if (filteredType.length === 1) {
4673
+ return filteredType.at(0);
4674
+ }
4675
+ return { ...type, types: filteredType };
4784
4676
  }
4785
4677
  }
4786
4678
  return type;
@@ -4795,11 +4687,26 @@ function isReadonlyProperty(symbol, compiler) {
4795
4687
  (symbol.flags & compiler.SymbolFlags.Accessor && !(symbol.flags & compiler.SymbolFlags.SetAccessor)));
4796
4688
  }
4797
4689
 
4690
+ class SeenService {
4691
+ #cache = new Map();
4692
+ memoized(a, b, compare) {
4693
+ const key = [a.id, b.id].sort().join(":");
4694
+ const result = this.#cache.get(key);
4695
+ if (result !== undefined) {
4696
+ return result !== 2;
4697
+ }
4698
+ this.#cache.set(key, 0);
4699
+ const isSame = compare();
4700
+ this.#cache.set(key, isSame ? 1 : 2);
4701
+ return isSame;
4702
+ }
4703
+ }
4704
+
4798
4705
  class Structure {
4799
4706
  #compiler;
4800
4707
  #compilerOptions;
4801
4708
  #program;
4802
- #resultCache = new Map();
4709
+ #seen = new SeenService();
4803
4710
  #typeChecker;
4804
4711
  constructor(compiler, program) {
4805
4712
  this.#compiler = compiler;
@@ -4821,7 +4728,7 @@ class Structure {
4821
4728
  compare(a, b) {
4822
4729
  a = this.#normalize(a);
4823
4730
  b = this.#normalize(b);
4824
- if (a === b) {
4731
+ if (a.id === b.id) {
4825
4732
  return true;
4826
4733
  }
4827
4734
  if (a.flags & this.#compiler.TypeFlags.Any) {
@@ -4833,75 +4740,132 @@ class Structure {
4833
4740
  if (a.flags & this.#compiler.TypeFlags.Undefined) {
4834
4741
  return !!(b.flags & this.#compiler.TypeFlags.Undefined);
4835
4742
  }
4836
- if (isIntersectionType(a, this.#compiler) || isIntersectionType(b, this.#compiler)) {
4837
- if (isIntersectionType(a, this.#compiler) &&
4838
- isIntersectionType(b, this.#compiler) &&
4839
- a.types.length === b.types.length &&
4840
- a.types.every((aType, i) => this.compare(aType, b.types[i]))) {
4841
- return true;
4842
- }
4843
- return (this.compareProperties(a, b) &&
4844
- this.compareSignatures(a, b, this.#compiler.SignatureKind.Call) &&
4845
- this.compareSignatures(a, b, this.#compiler.SignatureKind.Construct) &&
4846
- this.compareIndexSignatures(a, b));
4743
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Intersection) {
4744
+ return (((a.flags & b.flags & this.#compiler.TypeFlags.Intersection) !== 0 &&
4745
+ this.compareIntersections(a, b)) ||
4746
+ (((a.flags & b.flags) | this.#compiler.TypeFlags.StructuredType) !== 0 &&
4747
+ this.#seen.memoized(a, b, () => this.compareStructuredTypes(a, b))));
4847
4748
  }
4848
- if (isUnionType(a, this.#compiler) || isUnionType(b, this.#compiler)) {
4849
- if (isUnionType(a, this.#compiler) && isUnionType(b, this.#compiler)) {
4749
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Union) {
4750
+ if (a.flags & b.flags & this.#compiler.TypeFlags.Union) {
4850
4751
  return this.compareUnions(a, b);
4851
4752
  }
4852
4753
  return false;
4853
4754
  }
4854
- if (isTupleTypeReference(a, this.#compiler) || isTupleTypeReference(b, this.#compiler)) {
4855
- if (isTupleTypeReference(a, this.#compiler) && isTupleTypeReference(b, this.#compiler)) {
4856
- return this.compareTuples(a, b);
4755
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Object) {
4756
+ if (a.flags & b.flags & this.#compiler.TypeFlags.Object) {
4757
+ return this.#seen.memoized(a, b, () => this.compareObjects(a, b));
4758
+ }
4759
+ return false;
4760
+ }
4761
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.TypeParameter) {
4762
+ if (a.flags & b.flags & this.#compiler.TypeFlags.TypeParameter) {
4763
+ return this.compareTypeParameters(a, b);
4764
+ }
4765
+ return false;
4766
+ }
4767
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Index) {
4768
+ if (a.flags & b.flags & this.#compiler.TypeFlags.Index) {
4769
+ return this.compare(a.type, b.type);
4857
4770
  }
4858
4771
  return false;
4859
4772
  }
4860
- if (isTypeParameter(a, this.#compiler) || isTypeParameter(b, this.#compiler)) {
4861
- if (isTypeParameter(a, this.#compiler) && isTypeParameter(b, this.#compiler)) {
4862
- return this.compareTypeParameter(a, b);
4773
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.IndexedAccess) {
4774
+ if (a.flags & b.flags & this.#compiler.TypeFlags.IndexedAccess) {
4775
+ return this.compareIndexedAccessTypes(a, b);
4863
4776
  }
4864
4777
  return false;
4865
4778
  }
4866
- if (isConditionalType(a, this.#compiler) || isConditionalType(b, this.#compiler)) {
4867
- if (isConditionalType(a, this.#compiler) && isConditionalType(b, this.#compiler)) {
4779
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Conditional) {
4780
+ if (a.flags & b.flags & this.#compiler.TypeFlags.Conditional) {
4868
4781
  return this.compareConditionalTypes(a, b);
4869
4782
  }
4870
4783
  return false;
4871
4784
  }
4872
- if (isObjectType(a, this.#compiler) || isObjectType(b, this.#compiler)) {
4873
- if (isObjectType(a, this.#compiler) && isObjectType(b, this.#compiler)) {
4874
- return this.compareObjects(a, b);
4785
+ if ((a.flags | b.flags) & this.#compiler.TypeFlags.Substitution) {
4786
+ if (a.flags & b.flags & this.#compiler.TypeFlags.Substitution) {
4787
+ return this.compareSubstitutionTypes(a, b);
4875
4788
  }
4876
4789
  return false;
4877
4790
  }
4878
4791
  return false;
4879
4792
  }
4880
- compareConditionalTypes(a, b) {
4881
- return (this.compare(a.checkType, b.checkType) &&
4882
- this.compare(a.extendsType, b.extendsType) &&
4883
- this.compare(this.#typeChecker.getTypeAtLocation(a.root.node.trueType), this.#typeChecker.getTypeAtLocation(b.root.node.trueType)) &&
4884
- this.compare(this.#typeChecker.getTypeAtLocation(a.root.node.falseType), this.#typeChecker.getTypeAtLocation(b.root.node.falseType)));
4793
+ compareIntersections(a, b) {
4794
+ if (a.types.length !== b.types.length) {
4795
+ return false;
4796
+ }
4797
+ return a.types.every((aType, i) => this.compare(aType, b.types[i]));
4885
4798
  }
4886
- compareIndexSignatures(a, b) {
4887
- const aSignatures = this.#getIndexSignatures(a);
4888
- const bSignatures = this.#getIndexSignatures(b);
4889
- if (aSignatures.length !== bSignatures.length) {
4799
+ compareUnions(a, b) {
4800
+ if (a.types.length !== b.types.length) {
4890
4801
  return false;
4891
4802
  }
4892
- for (let i = 0; i < aSignatures.length; i++) {
4893
- if (aSignatures[i].isReadonly !== bSignatures[i].isReadonly) {
4803
+ return a.types.every((aType) => b.types.some((bType) => this.compare(aType, bType)));
4804
+ }
4805
+ compareObjects(a, b) {
4806
+ if (a.objectFlags & b.objectFlags & this.#compiler.ObjectFlags.Reference) {
4807
+ const isSame = this.compareTypeReferences(a, b);
4808
+ if (isSame != null) {
4809
+ return isSame;
4810
+ }
4811
+ }
4812
+ return this.compareStructuredTypes(a, b);
4813
+ }
4814
+ compareTypeReferences(a, b) {
4815
+ if ((a.target.objectFlags | b.target.objectFlags) & this.#compiler.ObjectFlags.Tuple) {
4816
+ if (a.target.objectFlags & b.target.objectFlags & this.#compiler.ObjectFlags.Tuple) {
4817
+ return this.compareTuples(a, b);
4818
+ }
4819
+ return false;
4820
+ }
4821
+ if ((a.objectFlags | b.objectFlags) & this.#compiler.ObjectFlags.Class) {
4822
+ return this.compareStructuredTypes(a, b);
4823
+ }
4824
+ if (!this.#compareTypeOfSymbol(a.symbol, b.symbol)) {
4825
+ if (isSymbolFromDefaultLibrary(a.symbol, this.#program) || isSymbolFromDefaultLibrary(b.symbol, this.#program)) {
4894
4826
  return false;
4895
4827
  }
4896
- if (!this.compare(aSignatures[i].keyType, bSignatures[i].keyType)) {
4828
+ return;
4829
+ }
4830
+ if (length(a.typeArguments) !== length(b.typeArguments)) {
4831
+ return false;
4832
+ }
4833
+ return ensureArray(a.typeArguments).every((type, i) => this.compare(type, ensureArray(b.typeArguments)[i]));
4834
+ }
4835
+ compareTuples(a, b) {
4836
+ if (a.target.readonly !== b.target.readonly) {
4837
+ return false;
4838
+ }
4839
+ const aTypeArguments = this.#typeChecker.getTypeArguments(a);
4840
+ const bTypeArguments = this.#typeChecker.getTypeArguments(b);
4841
+ if (length(aTypeArguments) !== length(bTypeArguments)) {
4842
+ return false;
4843
+ }
4844
+ for (let i = 0; i < aTypeArguments.length; i++) {
4845
+ if (a.target.elementFlags[i] !== b.target.elementFlags[i]) {
4897
4846
  return false;
4898
4847
  }
4899
- if (!this.compare(aSignatures[i].type, bSignatures[i].type)) {
4848
+ if (!this.compare(aTypeArguments[i], bTypeArguments[i])) {
4900
4849
  return false;
4901
4850
  }
4902
4851
  }
4903
4852
  return true;
4904
4853
  }
4854
+ compareStructuredTypes(a, b) {
4855
+ if (!this.compareProperties(a, b)) {
4856
+ return false;
4857
+ }
4858
+ if (!this.compareSignatures(a, b, this.#compiler.SignatureKind.Call)) {
4859
+ return false;
4860
+ }
4861
+ if (!this.compareSignatures(a, b, this.#compiler.SignatureKind.Construct)) {
4862
+ return false;
4863
+ }
4864
+ if (!this.compareIndexSignatures(a, b)) {
4865
+ return false;
4866
+ }
4867
+ return true;
4868
+ }
4905
4869
  compareProperties(a, b) {
4906
4870
  const aProperties = this.#typeChecker.getPropertiesOfType(a);
4907
4871
  const bProperties = this.#typeChecker.getPropertiesOfType(b);
@@ -4942,50 +4906,26 @@ class Structure {
4942
4906
  }
4943
4907
  return true;
4944
4908
  }
4945
- compareObjects(a, b) {
4946
- const key = this.#getCacheKey(a, b);
4947
- const result = this.#resultCache.get(key);
4948
- if (result != null) {
4949
- return result !== 2;
4950
- }
4951
- this.#resultCache.set(key, 0);
4952
- if (isTypeReference(a, this.#compiler) &&
4953
- !isClass(a, this.#compiler) &&
4954
- isTypeReference(b, this.#compiler) &&
4955
- !isClass(b, this.#compiler)) {
4956
- const isSame = this.compareTypeReferences(a, b);
4957
- if (isSame != null) {
4958
- this.#resultCache.set(key, isSame ? 1 : 2);
4959
- return isSame;
4960
- }
4961
- }
4962
- const isSame = this.compareProperties(a, b) &&
4963
- this.compareSignatures(a, b, this.#compiler.SignatureKind.Call) &&
4964
- this.compareSignatures(a, b, this.#compiler.SignatureKind.Construct) &&
4965
- this.compareIndexSignatures(a, b);
4966
- this.#resultCache.set(key, isSame ? 1 : 2);
4967
- return isSame;
4968
- }
4969
4909
  compareSignatures(a, b, kind) {
4970
- const aSignatures = this.#getSignatures(a, kind);
4971
- const bSignatures = this.#getSignatures(b, kind);
4972
- if (length(aSignatures) !== length(bSignatures)) {
4910
+ const aSignatures = getSignatures(a, kind, this.#compiler, this.#typeChecker);
4911
+ const bSignatures = getSignatures(b, kind, this.#compiler, this.#typeChecker);
4912
+ if (aSignatures.length !== bSignatures.length) {
4973
4913
  return false;
4974
4914
  }
4975
4915
  for (let i = 0; i < aSignatures.length; i++) {
4976
- if (!this.compareSignature(aSignatures[i], bSignatures[i])) {
4916
+ if (!this.#compareSignature(aSignatures[i], bSignatures[i])) {
4977
4917
  return false;
4978
4918
  }
4979
4919
  }
4980
4920
  return true;
4981
4921
  }
4982
- compareSignature(a, b) {
4922
+ #compareSignature(a, b) {
4983
4923
  if (length(a.typeParameters) !== length(b.typeParameters)) {
4984
4924
  return false;
4985
4925
  }
4986
4926
  if (a.typeParameters != null && b.typeParameters != null) {
4987
4927
  for (let i = 0; i < a.typeParameters.length; i++) {
4988
- if (!this.compareTypeParameter(a.typeParameters[i], b.typeParameters[i])) {
4928
+ if (!this.compareTypeParameters(a.typeParameters[i], b.typeParameters[i])) {
4989
4929
  return false;
4990
4930
  }
4991
4931
  }
@@ -5028,76 +4968,81 @@ class Structure {
5028
4968
  }
5029
4969
  return true;
5030
4970
  }
5031
- compareTuples(a, b) {
5032
- if (a.target.readonly !== b.target.readonly) {
5033
- return false;
5034
- }
5035
- const aTypeArguments = this.#typeChecker.getTypeArguments(a);
5036
- const bTypeArguments = this.#typeChecker.getTypeArguments(b);
5037
- if (length(aTypeArguments) !== length(bTypeArguments)) {
4971
+ compareIndexSignatures(a, b) {
4972
+ const aSignatures = getIndexSignatures(a, this.#compiler, this.#typeChecker);
4973
+ const bSignatures = getIndexSignatures(b, this.#compiler, this.#typeChecker);
4974
+ if (aSignatures.length !== bSignatures.length) {
5038
4975
  return false;
5039
4976
  }
5040
- for (let i = 0; i < aTypeArguments.length; i++) {
5041
- if (a.target.elementFlags[i] !== b.target.elementFlags[i]) {
4977
+ for (let i = 0; i < aSignatures.length; i++) {
4978
+ if (aSignatures[i].isReadonly !== bSignatures[i].isReadonly) {
5042
4979
  return false;
5043
4980
  }
5044
- if (!this.compare(aTypeArguments[i], bTypeArguments[i])) {
4981
+ if (!this.compare(aSignatures[i].keyType, bSignatures[i].keyType)) {
4982
+ return false;
4983
+ }
4984
+ if (!this.compare(aSignatures[i].type, bSignatures[i].type)) {
5045
4985
  return false;
5046
4986
  }
5047
4987
  }
5048
4988
  return true;
5049
4989
  }
5050
- compareTypeParameter(a, b) {
5051
- if (!this.#compareMaybeNullish(this.#typeChecker.getBaseConstraintOfType(a), this.#typeChecker.getBaseConstraintOfType(b)) ||
5052
- !this.#compareMaybeNullish(this.#typeChecker.getDefaultFromTypeParameter(a), this.#typeChecker.getDefaultFromTypeParameter(b))) {
4990
+ compareTypeParameters(a, b) {
4991
+ if (getTypeParameterModifiers(a, this.#compiler) !== getTypeParameterModifiers(b, this.#compiler)) {
4992
+ return false;
4993
+ }
4994
+ if (!this.#compareMaybeNullish(this.#typeChecker.getBaseConstraintOfType(a), this.#typeChecker.getBaseConstraintOfType(b))) {
4995
+ return false;
4996
+ }
4997
+ if (!this.#compareMaybeNullish(this.#typeChecker.getDefaultFromTypeParameter(a), this.#typeChecker.getDefaultFromTypeParameter(b))) {
5053
4998
  return false;
5054
4999
  }
5055
5000
  return true;
5056
5001
  }
5057
- compareTypeReferences(a, b) {
5058
- if (!this.#compareTypeOfSymbol(a.symbol, b.symbol)) {
5059
- if (isSymbolFromDefaultLibrary(a.symbol, this.#program) || isSymbolFromDefaultLibrary(b.symbol, this.#program)) {
5060
- return false;
5061
- }
5062
- return;
5002
+ compareIndexedAccessTypes(a, b) {
5003
+ if (!this.compare(a.objectType, b.objectType)) {
5004
+ return false;
5063
5005
  }
5064
- if (length(a.typeArguments) !== length(b.typeArguments)) {
5006
+ if (!this.compare(a.indexType, b.indexType)) {
5065
5007
  return false;
5066
5008
  }
5067
- return ensureArray(a.typeArguments).every((type, i) => this.compare(type, ensureArray(b.typeArguments)[i]));
5009
+ return true;
5068
5010
  }
5069
- compareUnions(a, b) {
5070
- if (a.types.length !== b.types.length) {
5011
+ compareConditionalTypes(a, b) {
5012
+ if (!this.compare(a.checkType, b.checkType)) {
5071
5013
  return false;
5072
5014
  }
5073
- return (a.types.every((aType) => b.types.some((bType) => this.compare(aType, bType))) &&
5074
- b.types.every((bType) => a.types.some((aType) => this.compare(bType, aType))));
5075
- }
5076
- #getCacheKey(a, b) {
5077
- return [a.id, b.id].sort().join(":");
5078
- }
5079
- #getSignatures(type, kind) {
5080
- if (isIntersectionType(type, this.#compiler)) {
5081
- return type.types.flatMap((type) => this.#getSignatures(type, kind));
5015
+ if (!this.compare(a.extendsType, b.extendsType)) {
5016
+ return false;
5017
+ }
5018
+ if (!this.compare(this.#typeChecker.getTypeAtLocation(a.root.node.trueType), this.#typeChecker.getTypeAtLocation(b.root.node.trueType))) {
5019
+ return false;
5020
+ }
5021
+ if (!this.compare(this.#typeChecker.getTypeAtLocation(a.root.node.falseType), this.#typeChecker.getTypeAtLocation(b.root.node.falseType))) {
5022
+ return false;
5082
5023
  }
5083
- return this.#typeChecker.getSignaturesOfType(type, kind);
5024
+ return true;
5084
5025
  }
5085
- #getIndexSignatures(type) {
5086
- if (isIntersectionType(type, this.#compiler)) {
5087
- return type.types.flatMap((type) => this.#getIndexSignatures(type));
5026
+ compareSubstitutionTypes(a, b) {
5027
+ if (!this.compare(a.baseType, b.baseType)) {
5028
+ return false;
5029
+ }
5030
+ if (!this.compare(a.constraint, b.constraint)) {
5031
+ return false;
5088
5032
  }
5089
- return this.#typeChecker.getIndexInfosOfType(type);
5033
+ return true;
5090
5034
  }
5091
5035
  #normalize(type) {
5092
- if (isFreshLiteralType(type, this.#compiler)) {
5036
+ if (type.flags & this.#compiler.TypeFlags.Freshable && type.freshType === type) {
5093
5037
  return type.regularType;
5094
5038
  }
5095
- if (isNoInferType(type, this.#compiler)) {
5039
+ if (type.flags & this.#compiler.TypeFlags.Substitution &&
5040
+ type.constraint.flags & this.#compiler.TypeFlags.Unknown) {
5096
5041
  return type.baseType;
5097
5042
  }
5098
- if (isUnionType(type, this.#compiler) || isIntersectionType(type, this.#compiler)) {
5043
+ if (type.flags & this.#compiler.TypeFlags.UnionOrIntersection) {
5099
5044
  const candidateType = this.#normalize(type.types[0]);
5100
- if (type.types.every((type) => this.compare(this.#normalize(type), candidateType))) {
5045
+ if (type.types.every((t) => this.compare(this.#normalize(t), candidateType))) {
5101
5046
  return candidateType;
5102
5047
  }
5103
5048
  }
@@ -5105,6 +5050,18 @@ class Structure {
5105
5050
  }
5106
5051
  }
5107
5052
 
5053
+ class RelationMatcherBase {
5054
+ explain(matchWorker, sourceNode, targetNode) {
5055
+ const sourceTypeText = matchWorker.getTypeText(sourceNode);
5056
+ const targetTypeText = matchWorker.getTypeText(targetNode);
5057
+ const text = matchWorker.assertionNode.isNot
5058
+ ? this.explainText(sourceTypeText, targetTypeText)
5059
+ : this.explainNotText(sourceTypeText, targetTypeText);
5060
+ const origin = DiagnosticOrigin.fromNode(targetNode, matchWorker.assertionNode);
5061
+ return [Diagnostic.error(text, origin)];
5062
+ }
5063
+ }
5064
+
5108
5065
  class ToBe extends RelationMatcherBase {
5109
5066
  #structure;
5110
5067
  constructor(compiler, program) {
@@ -5456,12 +5413,12 @@ class ExpectService {
5456
5413
  toBeConstructableWith;
5457
5414
  toHaveProperty;
5458
5415
  toRaiseError;
5459
- constructor(compiler, program, reject, resolvedConfig) {
5416
+ constructor(compiler, program, reject) {
5460
5417
  this.#compiler = compiler;
5461
5418
  this.#program = program;
5462
5419
  this.#reject = reject;
5463
5420
  this.toAcceptProps = new ToAcceptProps(compiler, program);
5464
- this.toBe = resolvedConfig.legacyToBe ? new LegacyToBe() : new ToBe(compiler, program);
5421
+ this.toBe = new ToBe(compiler, program);
5465
5422
  this.toBeApplicable = new ToBeApplicable(compiler);
5466
5423
  this.toBeAssignableFrom = new ToBeAssignableFrom();
5467
5424
  this.toBeAssignableTo = new ToBeAssignableTo();
@@ -5706,7 +5663,7 @@ class TestTreeWalker {
5706
5663
  this.#hasOnly = options.hasOnly || resolvedConfig.only != null || options.position != null;
5707
5664
  this.#position = options.position;
5708
5665
  const reject = new Reject(compiler, program, resolvedConfig);
5709
- this.#expectService = new ExpectService(compiler, program, reject, resolvedConfig);
5666
+ this.#expectService = new ExpectService(compiler, program, reject);
5710
5667
  this.#whenService = new WhenService(reject, onFileDiagnostics);
5711
5668
  }
5712
5669
  async #resolveRunMode(flags, node) {
@@ -5951,7 +5908,7 @@ class FileRunner {
5951
5908
  class Runner {
5952
5909
  #eventEmitter = new EventEmitter();
5953
5910
  #resolvedConfig;
5954
- static version = "6.0.0-beta.0";
5911
+ static version = "6.0.0-beta.2";
5955
5912
  constructor(resolvedConfig) {
5956
5913
  this.#resolvedConfig = resolvedConfig;
5957
5914
  }
@@ -6008,7 +5965,7 @@ class Runner {
6008
5965
  for (const target of this.#resolvedConfig.target) {
6009
5966
  const targetResult = new TargetResult(target, files);
6010
5967
  EventEmitter.dispatch(["target:start", { result: targetResult }]);
6011
- const compiler = await Store.load(target, { notPatched: !this.#resolvedConfig.legacyToBe });
5968
+ const compiler = await Store.load(target);
6012
5969
  if (compiler) {
6013
5970
  const fileRunner = new FileRunner(compiler, this.#resolvedConfig);
6014
5971
  for (const file of files) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tstyche",
3
- "version": "6.0.0-beta.0",
3
+ "version": "6.0.0-beta.2",
4
4
  "description": "Everything You Need for Type Testing.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -32,7 +32,7 @@
32
32
  "types": "./build/index.d.ts",
33
33
  "bin": "./build/bin.js",
34
34
  "peerDependencies": {
35
- "typescript": ">=5.0"
35
+ "typescript": ">=5.4"
36
36
  },
37
37
  "peerDependenciesMeta": {
38
38
  "typescript": {