@travetto/transformer 8.0.1 → 8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/transformer",
3
- "version": "8.0.1",
3
+ "version": "8.0.2",
4
4
  "description": "Functionality for AST transformations, with transformer registration, and general utils",
5
5
  "keywords": [
6
6
  "ast-transformations",
@@ -33,6 +33,24 @@ const getMappedFields = (type: ts.Type): string[] | undefined => {
33
33
  }
34
34
  };
35
35
 
36
+ const hasComplexSubType = (type: ts.UnionOrIntersectionType): boolean => {
37
+ if (type.types.filter(x => (x.getFlags() & (ts.TypeFlags.Undefined | ts.TypeFlags.Null)) === 0).length === 1) {
38
+ return false;
39
+ }
40
+
41
+ for (const sub of type.types) {
42
+ if (
43
+ sub.isClassOrInterface() ||
44
+ (sub.isUnionOrIntersection() && hasComplexSubType(sub)) ||
45
+ sub.getFlags() & ts.TypeFlags.Object ||
46
+ sub.getFlags() & ts.TypeFlags.NonPrimitive
47
+ ) {
48
+ return true;
49
+ }
50
+ }
51
+ return false;
52
+ };
53
+
36
54
  /**
37
55
  * List of global types that can be parameterized
38
56
  */
@@ -87,7 +105,11 @@ type Category = Exclude<AnyType['key'], 'pointer'> | 'concrete';
87
105
  /**
88
106
  * Type categorizer, input for builder
89
107
  */
90
- export function TypeCategorize(resolver: TransformResolver, type: ts.Type): { category: Category; type: ts.Type } {
108
+ export function TypeCategorize(
109
+ resolver: TransformResolver,
110
+ type: ts.Type,
111
+ context: { importName: string }
112
+ ): { category: Category; type: ts.Type } {
91
113
  const flags = type.getFlags();
92
114
  const objectFlags = DeclarationUtil.getObjectFlags(type) ?? 0;
93
115
 
@@ -113,6 +135,9 @@ export function TypeCategorize(resolver: TransformResolver, type: ts.Type): { ca
113
135
  // Tuple type?
114
136
  return { category: 'tuple', type };
115
137
  } else if (type.isUnionOrIntersection()) {
138
+ if (hasComplexSubType(type)) {
139
+ return { category: 'shape', type };
140
+ }
116
141
  return { category: 'composition', type };
117
142
  } else if (objectFlags & ts.ObjectFlags.Anonymous) {
118
143
  try {
@@ -88,7 +88,7 @@ export class SimpleResolver implements TransformResolver {
88
88
  getAllTypeArguments(ref: ts.Type): [templateName: string, type: ts.Type][] {
89
89
  const types = this.#tsChecker.getTypeArguments(transformCast(ref));
90
90
  let names: string[] | undefined;
91
- if (ref.symbol.declarations?.[0]) {
91
+ if (ref.symbol?.declarations?.[0]) {
92
92
  const first = ref.symbol.declarations[0];
93
93
  if (ts.isClassLike(first) || ts.isInterfaceDeclaration(first) || ts.isTypeAliasDeclaration(first)) {
94
94
  names = first.typeParameters?.map(tp => tp.name.getText()) ?? [];
@@ -135,7 +135,7 @@ export class SimpleResolver implements TransformResolver {
135
135
  throw new Error(`Object structure too nested: ${'getText' in node ? node.getText() : ''}`);
136
136
  }
137
137
 
138
- const { category, type } = TypeCategorize(this, resType);
138
+ const { category, type } = TypeCategorize(this, resType, { importName });
139
139
  // TODO: Figure out how to get this legitimately
140
140
  const typeArguments: ts.Type[] =
141
141
  'resolvedTypeArguments' in resType && resType.resolvedTypeArguments ? transformCast(resType.resolvedTypeArguments) : [];