@typespec/emitter-framework 0.3.0-dev.2 → 0.3.0-dev.4

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.
Files changed (64) hide show
  1. package/dist/src/testing/scenario-test/snippet-extractor.d.ts +2 -2
  2. package/dist/src/testing/scenario-test/snippet-extractor.d.ts.map +1 -1
  3. package/dist/src/testing/scenario-test/snippet-extractor.js +2 -1
  4. package/dist/src/testing/scenario-test/snippet-extractor.js.map +1 -1
  5. package/dist/src/typescript/components/array-expression.d.ts +2 -1
  6. package/dist/src/typescript/components/array-expression.d.ts.map +1 -1
  7. package/dist/src/typescript/components/array-expression.js +3 -2
  8. package/dist/src/typescript/components/array-expression.js.map +1 -1
  9. package/dist/src/typescript/components/class-method.d.ts.map +1 -1
  10. package/dist/src/typescript/components/class-method.js.map +1 -1
  11. package/dist/src/typescript/components/enum-declaration.d.ts +4 -4
  12. package/dist/src/typescript/components/enum-declaration.d.ts.map +1 -1
  13. package/dist/src/typescript/components/enum-declaration.js +19 -15
  14. package/dist/src/typescript/components/enum-declaration.js.map +1 -1
  15. package/dist/src/typescript/components/function-declaration.d.ts.map +1 -1
  16. package/dist/src/typescript/components/function-declaration.js +1 -1
  17. package/dist/src/typescript/components/function-declaration.js.map +1 -1
  18. package/dist/src/typescript/components/interface-declaration.d.ts +3 -3
  19. package/dist/src/typescript/components/interface-declaration.d.ts.map +1 -1
  20. package/dist/src/typescript/components/interface-declaration.js +14 -7
  21. package/dist/src/typescript/components/interface-declaration.js.map +1 -1
  22. package/dist/src/typescript/components/interface-member.d.ts.map +1 -1
  23. package/dist/src/typescript/components/interface-member.js.map +1 -1
  24. package/dist/src/typescript/components/record-expression.js.map +1 -1
  25. package/dist/src/typescript/components/static-serializers.d.ts.map +1 -1
  26. package/dist/src/typescript/components/static-serializers.js +8 -8
  27. package/dist/src/typescript/components/static-serializers.js.map +1 -1
  28. package/dist/src/typescript/components/type-alias-declaration.d.ts.map +1 -1
  29. package/dist/src/typescript/components/type-alias-declaration.js +1 -1
  30. package/dist/src/typescript/components/type-alias-declaration.js.map +1 -1
  31. package/dist/src/typescript/components/type-declaration.js.map +1 -1
  32. package/dist/src/typescript/components/type-expression.d.ts.map +1 -1
  33. package/dist/src/typescript/components/type-expression.js +12 -5
  34. package/dist/src/typescript/components/type-expression.js.map +1 -1
  35. package/dist/src/typescript/components/type-transform.d.ts.map +1 -1
  36. package/dist/src/typescript/components/type-transform.js +29 -27
  37. package/dist/src/typescript/components/type-transform.js.map +1 -1
  38. package/dist/src/typescript/components/union-declaration.d.ts.map +1 -1
  39. package/dist/src/typescript/components/union-declaration.js.map +1 -1
  40. package/dist/src/typescript/components/union-expression.d.ts +2 -1
  41. package/dist/src/typescript/components/union-expression.d.ts.map +1 -1
  42. package/dist/src/typescript/components/union-expression.js +23 -24
  43. package/dist/src/typescript/components/union-expression.js.map +1 -1
  44. package/package.json +7 -7
  45. package/src/testing/scenario-test/snippet-extractor.ts +4 -3
  46. package/src/typescript/components/array-expression.tsx +2 -3
  47. package/src/typescript/components/class-method.tsx +14 -9
  48. package/src/typescript/components/enum-declaration.tsx +31 -28
  49. package/src/typescript/components/function-declaration.tsx +8 -4
  50. package/src/typescript/components/interface-declaration.tsx +23 -10
  51. package/src/typescript/components/interface-member.tsx +8 -4
  52. package/src/typescript/components/record-expression.tsx +1 -1
  53. package/src/typescript/components/static-serializers.tsx +78 -18
  54. package/src/typescript/components/type-alias-declaration.tsx +6 -4
  55. package/src/typescript/components/type-declaration.tsx +1 -1
  56. package/src/typescript/components/type-expression.tsx +10 -8
  57. package/src/typescript/components/type-transform.tsx +83 -46
  58. package/src/typescript/components/union-declaration.tsx +4 -2
  59. package/src/typescript/components/union-expression.tsx +25 -22
  60. package/test/typescript/components/enum-declaration.test.tsx +19 -11
  61. package/test/typescript/components/interface-declaration.test.tsx +41 -40
  62. package/test/typescript/components/member-expression.test.tsx +25 -16
  63. package/test/typescript/components/type-transform.test.tsx +21 -6
  64. package/test/typescript/components/union-declaration.test.tsx +6 -10
@@ -1,3 +1,4 @@
1
+ import * as ay from "@alloy-js/core";
1
2
  import { Children, refkey as getRefkey, mapJoin } from "@alloy-js/core";
2
3
  import * as ts from "@alloy-js/typescript";
3
4
  import { Interface, Model, ModelProperty, Operation, RekeyableMap } from "@typespec/compiler";
@@ -34,7 +35,7 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
34
35
 
35
36
  const extendsType = props.extends ?? getExtendsType(props.type);
36
37
 
37
- const members = props.type ? membersFromType(props.type) : [];
38
+ const members = props.type ? [membersFromType(props.type)] : [];
38
39
 
39
40
  const children = [...members];
40
41
 
@@ -44,7 +45,8 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
44
45
  children.push(props.children);
45
46
  }
46
47
 
47
- return <ts.InterfaceDeclaration
48
+ return (
49
+ <ts.InterfaceDeclaration
48
50
  default={props.default}
49
51
  export={props.export}
50
52
  kind={props.kind}
@@ -53,7 +55,8 @@ export function InterfaceDeclaration(props: InterfaceDeclarationProps) {
53
55
  extends={extendsType}
54
56
  >
55
57
  {children}
56
- </ts.InterfaceDeclaration>;
58
+ </ts.InterfaceDeclaration>
59
+ );
57
60
  }
58
61
 
59
62
  function isTypedInterfaceDeclarationProps(
@@ -69,12 +72,14 @@ export interface InterfaceExpressionProps extends ts.InterfaceExpressionProps {
69
72
  export function InterfaceExpression({ type, children }: InterfaceExpressionProps) {
70
73
  const members = type ? membersFromType(type) : [];
71
74
 
72
- return <>
75
+ return (
76
+ <>
73
77
  {"{"}
74
78
  {members}
75
79
  {children}
76
80
  {"}"}
77
- </>;
81
+ </>
82
+ );
78
83
  }
79
84
 
80
85
  function getExtendsType(type: Model | Interface): Children | undefined {
@@ -112,10 +117,14 @@ function getExtendsType(type: Model | Interface): Children | undefined {
112
117
  return undefined;
113
118
  }
114
119
 
115
- return mapJoin(extending, (ext) => ext, { joiner: "," });
120
+ return mapJoin(
121
+ () => extending,
122
+ (ext) => ext,
123
+ { joiner: "," },
124
+ );
116
125
  }
117
126
 
118
- function membersFromType(type: Model | Interface) {
127
+ function membersFromType(type: Model | Interface): Children {
119
128
  let typeMembers: RekeyableMap<string, ModelProperty | Operation> | undefined;
120
129
  if ($.model.is(type)) {
121
130
  typeMembers = $.model.getProperties(type);
@@ -134,7 +143,11 @@ function membersFromType(type: Model | Interface) {
134
143
  typeMembers = createRekeyableMap(type.operations);
135
144
  }
136
145
 
137
- return mapJoin(typeMembers, (_, prop) => <InterfaceMember type={prop} />, {
138
- joiner: "\n",
139
- });
146
+ return (
147
+ <ay.For each={Array.from(typeMembers.entries())} line>
148
+ {([_, prop]) => {
149
+ return <InterfaceMember type={prop} />;
150
+ }}
151
+ </ay.For>
152
+ );
140
153
  }
@@ -27,16 +27,20 @@ export function InterfaceMember({ type, optional }: InterfaceMemberProps) {
27
27
  unpackedType = part.type;
28
28
  }
29
29
 
30
- return <>
30
+ return (
31
+ <>
31
32
  "{name}"{optionality}: <TypeExpression type={unpackedType} />;
32
- </>;
33
+ </>
34
+ );
33
35
  }
34
36
 
35
37
  if ($.operation.is(type)) {
36
38
  const returnType = <TypeExpression type={type.returnType} />;
37
39
  const params = <FunctionDeclaration.Parameters type={type.parameters} />;
38
- return <>
40
+ return (
41
+ <>
39
42
  {name}({params}): {returnType};
40
- </>;
43
+ </>
44
+ );
41
45
  }
42
46
  }
@@ -8,6 +8,6 @@ export interface RecordExpressionProps {
8
8
 
9
9
  export function RecordExpression({ elementType }: RecordExpressionProps) {
10
10
  return code`
11
- Record<string, ${<TypeExpression type={elementType} />}>
11
+ Record<string, ${(<TypeExpression type={elementType} />)}>
12
12
  `;
13
13
  }
@@ -3,7 +3,13 @@ import * as ts from "@alloy-js/typescript";
3
3
 
4
4
  export const DateRfc3339SerializerRefkey = refkey();
5
5
  export function DateRfc3339Serializer() {
6
- return <ts.FunctionDeclaration export name="DateRfc3339Serializer" returnType="string" refkey={DateRfc3339SerializerRefkey}>
6
+ return (
7
+ <ts.FunctionDeclaration
8
+ export
9
+ name="DateRfc3339Serializer"
10
+ returnType="string"
11
+ refkey={DateRfc3339SerializerRefkey}
12
+ >
7
13
  <ts.FunctionDeclaration.Parameters>date?: Date | null</ts.FunctionDeclaration.Parameters>
8
14
  {code`
9
15
  if (!date) {
@@ -12,12 +18,19 @@ export function DateRfc3339Serializer() {
12
18
 
13
19
  return date.toISOString();
14
20
  `}
15
- </ts.FunctionDeclaration>;
21
+ </ts.FunctionDeclaration>
22
+ );
16
23
  }
17
24
 
18
25
  export const DateRfc7231SerializerRefkey = refkey();
19
26
  export function DateRfc7231Serializer() {
20
- return <ts.FunctionDeclaration export name="DateRfc7231Serializer" returnType="string" refkey={DateRfc7231SerializerRefkey}>
27
+ return (
28
+ <ts.FunctionDeclaration
29
+ export
30
+ name="DateRfc7231Serializer"
31
+ returnType="string"
32
+ refkey={DateRfc7231SerializerRefkey}
33
+ >
21
34
  <ts.FunctionDeclaration.Parameters>date?: Date | null</ts.FunctionDeclaration.Parameters>
22
35
  {code`
23
36
  if (!date) {
@@ -26,12 +39,19 @@ export function DateRfc7231Serializer() {
26
39
 
27
40
  return date.toUTCString();
28
41
  `}
29
- </ts.FunctionDeclaration>;
42
+ </ts.FunctionDeclaration>
43
+ );
30
44
  }
31
45
 
32
46
  export const DateDeserializerRefkey = refkey();
33
47
  export function DateDeserializer() {
34
- return <ts.FunctionDeclaration export name="DateDeserializer" returnType="Date" refkey={DateDeserializerRefkey}>
48
+ return (
49
+ <ts.FunctionDeclaration
50
+ export
51
+ name="DateDeserializer"
52
+ returnType="Date"
53
+ refkey={DateDeserializerRefkey}
54
+ >
35
55
  <ts.FunctionDeclaration.Parameters>date?: string | null</ts.FunctionDeclaration.Parameters>
36
56
  {code`
37
57
  if (!date) {
@@ -40,12 +60,19 @@ export function DateDeserializer() {
40
60
 
41
61
  return new Date(date);
42
62
  `}
43
- </ts.FunctionDeclaration>;
63
+ </ts.FunctionDeclaration>
64
+ );
44
65
  }
45
66
 
46
67
  export const DateUnixTimestampDeserializerRefkey = refkey();
47
68
  export function DateUnixTimestampDeserializer() {
48
- return <ts.FunctionDeclaration export name="DateUnixTimestampDeserializer" returnType="Date" refkey={DateUnixTimestampDeserializerRefkey}>
69
+ return (
70
+ <ts.FunctionDeclaration
71
+ export
72
+ name="DateUnixTimestampDeserializer"
73
+ returnType="Date"
74
+ refkey={DateUnixTimestampDeserializerRefkey}
75
+ >
49
76
  <ts.FunctionDeclaration.Parameters>date?: number | null</ts.FunctionDeclaration.Parameters>
50
77
  {code`
51
78
  if (!date) {
@@ -54,12 +81,19 @@ export function DateUnixTimestampDeserializer() {
54
81
 
55
82
  return new Date(date * 1000);
56
83
  `}
57
- </ts.FunctionDeclaration>;
84
+ </ts.FunctionDeclaration>
85
+ );
58
86
  }
59
87
 
60
88
  export const DateRfc7231DeserializerRefkey = refkey();
61
89
  export function DateRfc7231Deserializer() {
62
- return <ts.FunctionDeclaration export name="DateRfc7231Deserializer" returnType="Date" refkey={DateRfc7231DeserializerRefkey}>
90
+ return (
91
+ <ts.FunctionDeclaration
92
+ export
93
+ name="DateRfc7231Deserializer"
94
+ returnType="Date"
95
+ refkey={DateRfc7231DeserializerRefkey}
96
+ >
63
97
  <ts.FunctionDeclaration.Parameters>date?: string | null</ts.FunctionDeclaration.Parameters>
64
98
  {code`
65
99
  if (!date) {
@@ -68,12 +102,19 @@ export function DateRfc7231Deserializer() {
68
102
 
69
103
  return new Date(date);
70
104
  `}
71
- </ts.FunctionDeclaration>;
105
+ </ts.FunctionDeclaration>
106
+ );
72
107
  }
73
108
 
74
109
  export const DateUnixTimestampSerializerRefkey = refkey();
75
110
  export function DateUnixTimestampSerializer() {
76
- return <ts.FunctionDeclaration export name="DateUnixTimestampSerializer" returnType="number" refkey={DateUnixTimestampSerializerRefkey}>
111
+ return (
112
+ <ts.FunctionDeclaration
113
+ export
114
+ name="DateUnixTimestampSerializer"
115
+ returnType="number"
116
+ refkey={DateUnixTimestampSerializerRefkey}
117
+ >
77
118
  <ts.FunctionDeclaration.Parameters>date?: Date | null</ts.FunctionDeclaration.Parameters>
78
119
  {code`
79
120
  if (!date) {
@@ -82,15 +123,24 @@ export function DateUnixTimestampSerializer() {
82
123
 
83
124
  return Math.floor(date.getTime() / 1000);
84
125
  `}
85
- </ts.FunctionDeclaration>;
126
+ </ts.FunctionDeclaration>
127
+ );
86
128
  }
87
129
 
88
130
  export const RecordSerializerRefkey = refkey();
89
131
  export function RecordSerializer() {
90
132
  const recordType = `Record<string, any>`;
91
133
  const convertFnType = `(item: any) => any`;
92
- return <ts.FunctionDeclaration export name="RecordSerializer" returnType={recordType} refkey={RecordSerializerRefkey}>
93
- <ts.FunctionDeclaration.Parameters>record?: {recordType}, convertFn?: {convertFnType}</ts.FunctionDeclaration.Parameters>
134
+ return (
135
+ <ts.FunctionDeclaration
136
+ export
137
+ name="RecordSerializer"
138
+ returnType={recordType}
139
+ refkey={RecordSerializerRefkey}
140
+ >
141
+ <ts.FunctionDeclaration.Parameters>
142
+ record?: {recordType}, convertFn?: {convertFnType}
143
+ </ts.FunctionDeclaration.Parameters>
94
144
  {code`
95
145
  if (!record) {
96
146
  return record as any;
@@ -106,15 +156,24 @@ export function RecordSerializer() {
106
156
 
107
157
  return output;
108
158
  `}
109
- </ts.FunctionDeclaration>;
159
+ </ts.FunctionDeclaration>
160
+ );
110
161
  }
111
162
 
112
163
  export const ArraySerializerRefkey = refkey();
113
164
  export function ArraySerializer() {
114
165
  const arrayType = `any[]`;
115
166
  const convertFnType = `(item: any) => any`;
116
- return <ts.FunctionDeclaration export name="ArraySerializer" returnType={arrayType} refkey={ArraySerializerRefkey}>
117
- <ts.FunctionDeclaration.Parameters>items?: {arrayType}, convertFn?: {convertFnType}</ts.FunctionDeclaration.Parameters>
167
+ return (
168
+ <ts.FunctionDeclaration
169
+ export
170
+ name="ArraySerializer"
171
+ returnType={arrayType}
172
+ refkey={ArraySerializerRefkey}
173
+ >
174
+ <ts.FunctionDeclaration.Parameters>
175
+ items?: {arrayType}, convertFn?: {convertFnType}
176
+ </ts.FunctionDeclaration.Parameters>
118
177
  {code`
119
178
  if (!items) {
120
179
  return items as any;
@@ -132,5 +191,6 @@ export function ArraySerializer() {
132
191
 
133
192
  return output;
134
193
  `}
135
- </ts.FunctionDeclaration>;
194
+ </ts.FunctionDeclaration>
195
+ );
136
196
  }
@@ -24,10 +24,12 @@ export function TypeAliasDeclaration(props: TypeAliasDeclarationProps) {
24
24
  }
25
25
 
26
26
  const name = ts.useTSNamePolicy().getName(originalName, "type");
27
- return <ts.TypeDeclaration {...props} name={name} refkey={props.refkey ?? getRefkey(props.type)}>
28
- <TypeExpression type={props.type} />
29
- {props.children}
30
- </ts.TypeDeclaration>;
27
+ return (
28
+ <ts.TypeDeclaration {...props} name={name} refkey={props.refkey ?? getRefkey(props.type)}>
29
+ <TypeExpression type={props.type} />
30
+ {props.children}
31
+ </ts.TypeDeclaration>
32
+ );
31
33
  }
32
34
 
33
35
  function isTypedAliasDeclarationProps(
@@ -14,7 +14,7 @@ export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
14
14
 
15
15
  export function TypeDeclaration(props: TypeDeclarationProps) {
16
16
  if (!props.type) {
17
- return <ts.TypeDeclaration {...props as WithRequired<ts.TypeDeclarationProps, "name">} />;
17
+ return <ts.TypeDeclaration {...(props as WithRequired<ts.TypeDeclarationProps, "name">)} />;
18
18
  }
19
19
 
20
20
  const { type, ...restProps } = props;
@@ -1,4 +1,4 @@
1
- import { refkey } from "@alloy-js/core";
1
+ import { For, refkey } from "@alloy-js/core";
2
2
  import { Reference, ValueExpression } from "@alloy-js/typescript";
3
3
  import { IntrinsicType, Model, Scalar, Type } from "@typespec/compiler";
4
4
  import { $ } from "@typespec/compiler/experimental/typekit";
@@ -36,13 +36,15 @@ export function TypeExpression(props: TypeExpressionProps) {
36
36
  case "UnionVariant":
37
37
  return <TypeExpression type={type.type} />;
38
38
  case "Tuple":
39
- return <>
40
- [{type.values.map((element) => (
41
- <>
42
- <TypeExpression type={element} />,
43
- </>
44
- ))}]
45
- </>;
39
+ return (
40
+ <>
41
+ [
42
+ <For each={type.values} comma line>
43
+ {(element) => <TypeExpression type={element} />}
44
+ </For>
45
+ ]
46
+ </>
47
+ );
46
48
  case "ModelProperty":
47
49
  return <TypeExpression type={type.type} />;
48
50
  case "Model":
@@ -1,4 +1,4 @@
1
- import { Children, code, mapJoin, Refkey, refkey } from "@alloy-js/core";
1
+ import { Children, code, For, mapJoin, Refkey, refkey } from "@alloy-js/core";
2
2
  import * as ts from "@alloy-js/typescript";
3
3
  import {
4
4
  Discriminator,
@@ -45,7 +45,9 @@ function UnionTransformExpression(props: UnionTransformProps) {
45
45
  return null;
46
46
  }
47
47
 
48
- return <DiscriminateExpression type={props.type} discriminator={discriminator} target={props.target} />;
48
+ return (
49
+ <DiscriminateExpression type={props.type} discriminator={discriminator} target={props.target} />
50
+ );
49
51
  }
50
52
 
51
53
  interface DiscriminateExpressionProps {
@@ -60,20 +62,19 @@ function DiscriminateExpression(props: DiscriminateExpressionProps) {
60
62
  const discriminatorRef = `item.${props.discriminator.propertyName}`;
61
63
 
62
64
  const unhandledVariant = `
63
- \n\nconsole.warn(\`Received unknown snake kind: \${${discriminatorRef}}\`);
65
+ \n\nconsole.warn(\`Received unknown kind: \${${discriminatorRef}}\`);
64
66
  return item as any;
65
67
  `;
66
68
 
67
- return mapJoin(
68
- discriminatedUnion.variants,
69
- (name, variant) => {
70
- return code`
71
- if( ${discriminatorRef} === ${JSON.stringify(name)}) {
72
- return ${<TypeTransformCall type={variant} target={props.target} castInput itemPath={["item"]}/>}
73
- }
74
- `;
75
- },
76
- { joiner: "\n\n", ender: unhandledVariant },
69
+ return (
70
+ <For each={discriminatedUnion.variants} ender={unhandledVariant}>
71
+ {(name, variant) => {
72
+ return code`
73
+ if( ${discriminatorRef} === ${JSON.stringify(name)}) {
74
+ return ${(<TypeTransformCall type={variant} target={props.target} castInput itemPath={["item"]} />)}
75
+ }`;
76
+ }}
77
+ </For>
77
78
  );
78
79
  }
79
80
 
@@ -113,9 +114,16 @@ export function TypeTransformDeclaration(props: TypeTransformProps) {
113
114
  const discriminator = $.type.getDiscriminator(props.type);
114
115
 
115
116
  transformExpression = discriminator ? (
116
- <DiscriminateExpression type={props.type} discriminator={discriminator} target={props.target} />
117
+ <DiscriminateExpression
118
+ type={props.type}
119
+ discriminator={discriminator}
120
+ target={props.target}
121
+ />
117
122
  ) : (
118
- <>return <ModelTransformExpression type={props.type} itemPath={["item"]} target={props.target} />;</>
123
+ <>
124
+ return{" "}
125
+ <ModelTransformExpression type={props.type} itemPath={["item"]} target={props.target} />;
126
+ </>
119
127
  );
120
128
  } else if ($.union.is(props.type)) {
121
129
  transformExpression = <UnionTransformExpression type={props.type} target={props.target} />;
@@ -130,7 +138,8 @@ export function TypeTransformDeclaration(props: TypeTransformProps) {
130
138
 
131
139
  const ref = props.refkey ?? getTypeTransformerRefkey(props.type, props.target);
132
140
 
133
- return <ts.FunctionDeclaration
141
+ return (
142
+ <ts.FunctionDeclaration
134
143
  export
135
144
  name={functionName}
136
145
  refkey={ref}
@@ -138,7 +147,8 @@ export function TypeTransformDeclaration(props: TypeTransformProps) {
138
147
  returnType={returnType}
139
148
  >
140
149
  {transformExpression}
141
- </ts.FunctionDeclaration>;
150
+ </ts.FunctionDeclaration>
151
+ );
142
152
  }
143
153
 
144
154
  /**
@@ -188,13 +198,14 @@ export function ModelTransformExpression(props: ModelTransformExpressionProps) {
188
198
 
189
199
  let baseModelTransform: Children = null;
190
200
  if (props.type.baseModel) {
191
- baseModelTransform = code`...${<ModelTransformExpression type={props.type.baseModel} itemPath={props.itemPath} target={props.target} optionsBagName={props.optionsBagName} />},\n`;
201
+ baseModelTransform = code`...${(<ModelTransformExpression type={props.type.baseModel} itemPath={props.itemPath} target={props.target} optionsBagName={props.optionsBagName} />)},\n`;
192
202
  }
193
203
 
194
- return <ts.ObjectExpression>
204
+ return (
205
+ <ts.ObjectExpression>
195
206
  {baseModelTransform}
196
207
  {mapJoin(
197
- modelProperties,
208
+ () => modelProperties,
198
209
  (_, property) => {
199
210
  const unpackedType = $.httpPart.unpack(property.type) ?? property.type;
200
211
  let targetPropertyName = property.name;
@@ -207,21 +218,30 @@ export function ModelTransformExpression(props: ModelTransformExpressionProps) {
207
218
  }
208
219
 
209
220
  const itemPath = [...(props.itemPath ?? []), sourcePropertyName];
210
- if(property.optional && props.optionsBagName) {
221
+ if (property.optional && props.optionsBagName) {
211
222
  itemPath.unshift(`${props.optionsBagName}?`);
212
223
  }
213
224
 
214
- let value = <TypeTransformCall target={props.target} type={unpackedType} itemPath={itemPath} />
215
-
216
- if(property.optional && needsTransform(unpackedType)) {
217
- value = <>{itemPath.join(".")} ? <TypeTransformCall target={props.target} type={unpackedType} itemPath={itemPath} /> : {itemPath.join(".")}</>
225
+ let value = (
226
+ <TypeTransformCall target={props.target} type={unpackedType} itemPath={itemPath} />
227
+ );
228
+
229
+ if (property.optional && needsTransform(unpackedType)) {
230
+ value = (
231
+ <>
232
+ {itemPath.join(".")} ?{" "}
233
+ <TypeTransformCall target={props.target} type={unpackedType} itemPath={itemPath} />{" "}
234
+ : {itemPath.join(".")}
235
+ </>
236
+ );
218
237
  }
219
238
 
220
239
  return <ts.ObjectProperty name={JSON.stringify(targetPropertyName)} value={value} />;
221
240
  },
222
- { joiner: ",\n" }
241
+ { joiner: ",\n" },
223
242
  )}
224
- </ts.ObjectExpression>;
243
+ </ts.ObjectExpression>
244
+ );
225
245
  }
226
246
 
227
247
  interface TransformReferenceProps {
@@ -239,13 +259,13 @@ function TransformReference(props: TransformReferenceProps) {
239
259
 
240
260
  if ($.model.is(props.type) && $.array.is(props.type)) {
241
261
  return code`
242
- (i: any) => ${<ts.FunctionCallExpression refkey={ArraySerializerRefkey} args={["i", <TransformReference target={props.target} type={$.array.getElementType(props.type)} />]} />}
262
+ (i: any) => ${(<ts.FunctionCallExpression target={ArraySerializerRefkey} args={["i", <TransformReference target={props.target} type={$.array.getElementType(props.type)} />]} />)}
243
263
  `;
244
264
  }
245
265
 
246
266
  if ($.model.is(props.type) && $.record.is(props.type)) {
247
267
  return code`
248
- (i: any) => ${<ts.FunctionCallExpression refkey={RecordSerializerRefkey} args={["i", <TransformReference target={props.target} type={$.record.getElementType(props.type)} />]} />}
268
+ (i: any) => ${(<ts.FunctionCallExpression target={RecordSerializerRefkey} args={["i", <TransformReference target={props.target} type={$.record.getElementType(props.type)} />]} />)}
249
269
  `;
250
270
  }
251
271
 
@@ -328,39 +348,56 @@ export function TypeTransformCall(props: TypeTransformCallProps) {
328
348
  const unpackedElement =
329
349
  $.httpPart.unpack($.array.getElementType(transformType)) ??
330
350
  $.array.getElementType(transformType);
331
- return <ts.FunctionCallExpression
332
- refkey={ArraySerializerRefkey}
333
- args={[
334
- itemName,
335
- <TransformReference target={props.target} type={unpackedElement} />,
336
- ]}
337
- />;
351
+ return (
352
+ <ts.FunctionCallExpression
353
+ target={ArraySerializerRefkey}
354
+ args={[itemName, <TransformReference target={props.target} type={unpackedElement} />]}
355
+ />
356
+ );
338
357
  }
339
358
 
340
359
  if ($.model.is(transformType) && $.record.is(transformType)) {
341
360
  const unpackedElement =
342
361
  $.httpPart.unpack($.record.getElementType(transformType)) ??
343
362
  $.record.getElementType(transformType);
344
- return <ts.FunctionCallExpression
345
- refkey={RecordSerializerRefkey}
346
- args={[
347
- itemName,
348
- <TransformReference target={props.target} type={unpackedElement} />,
349
- ]}
350
- />;
363
+ return (
364
+ <ts.FunctionCallExpression
365
+ target={RecordSerializerRefkey}
366
+ args={[itemName, <TransformReference target={props.target} type={unpackedElement} />]}
367
+ />
368
+ );
351
369
  }
352
370
 
353
371
  if ($.scalar.isUtcDateTime(transformType)) {
354
- return <ts.FunctionCallExpression refkey={props.target === "application" ? DateDeserializerRefkey : DateRfc3339SerializerRefkey} args={[itemName]} />;
372
+ return (
373
+ <ts.FunctionCallExpression
374
+ target={
375
+ props.target === "application" ? DateDeserializerRefkey : DateRfc3339SerializerRefkey
376
+ }
377
+ args={[itemName]}
378
+ />
379
+ );
355
380
  }
356
381
 
357
382
  if ($.model.is(transformType)) {
358
383
  if ($.model.isExpresion(transformType)) {
359
384
  const effectiveModel = $.model.getEffectiveModel(transformType);
360
385
 
361
- return <ModelTransformExpression type={effectiveModel} itemPath={itemPath} target={props.target} optionsBagName={props.optionsBagName} />;
386
+ return (
387
+ <ModelTransformExpression
388
+ type={effectiveModel}
389
+ itemPath={itemPath}
390
+ target={props.target}
391
+ optionsBagName={props.optionsBagName}
392
+ />
393
+ );
362
394
  }
363
- return <ts.FunctionCallExpression refkey={ getTypeTransformerRefkey(transformType, props.target)} args={[itemName]} />;
395
+ return (
396
+ <ts.FunctionCallExpression
397
+ target={getTypeTransformerRefkey(transformType, props.target)}
398
+ args={[itemName]}
399
+ />
400
+ );
364
401
  }
365
402
 
366
403
  return itemName;
@@ -28,9 +28,11 @@ export function UnionDeclaration(props: UnionDeclarationProps) {
28
28
 
29
29
  const name = ts.useTSNamePolicy().getName(originalName!, "type");
30
30
 
31
- return <ts.TypeDeclaration {...props} name={name} refkey={refkey}>
31
+ return (
32
+ <ts.TypeDeclaration {...props} name={name} refkey={refkey}>
32
33
  <UnionExpression type={type}>{coreProps.children}</UnionExpression>
33
- </ts.TypeDeclaration>;
34
+ </ts.TypeDeclaration>
35
+ );
34
36
  }
35
37
 
36
38
  function isTypedUnionDeclarationProps(
@@ -1,7 +1,9 @@
1
- import { Children, mapJoin } from "@alloy-js/core";
1
+ import * as ay from "@alloy-js/core";
2
+ import { Children } from "@alloy-js/core";
2
3
  import * as ts from "@alloy-js/typescript";
3
- import { Enum, Union } from "@typespec/compiler";
4
- import { TypeExpression } from "./type-expression.js";
4
+ import { Enum, EnumMember, Union, UnionVariant } from "@typespec/compiler";
5
+ import { $ } from "@typespec/compiler/experimental/typekit";
6
+ import { TypeExpression } from "./type-expression.jsx";
5
7
 
6
8
  export interface UnionExpressionProps {
7
9
  type: Union | Enum;
@@ -9,28 +11,29 @@ export interface UnionExpressionProps {
9
11
  }
10
12
 
11
13
  export function UnionExpression({ type, children }: UnionExpressionProps) {
12
- let variants: any[];
14
+ const items = ($.union.is(type) ? type.variants : type.members) as Map<
15
+ string,
16
+ UnionVariant | EnumMember
17
+ >;
13
18
 
14
- if (type.kind === "Enum") {
15
- variants = mapJoin(
16
- type.members,
17
- (_, value) => {
18
- return <ts.ValueExpression jsValue={value.value ?? value.name} />;
19
- },
20
- { joiner: " | " },
21
- );
22
- } else {
23
- variants = mapJoin(
24
- type.variants,
25
- (_, variant) => {
26
- return <TypeExpression type={variant.type} />;
27
- },
28
- { joiner: " | " },
29
- );
30
- }
19
+ const variants = (
20
+ <ay.For joiner={" | "} each={items}>
21
+ {(_, value) => {
22
+ if ($.enumMember.is(value)) {
23
+ return <ts.ValueExpression jsValue={value.value ?? value.name} />;
24
+ } else {
25
+ return <TypeExpression type={value.type} />;
26
+ }
27
+ }}
28
+ </ay.For>
29
+ );
31
30
 
32
31
  if (children || (Array.isArray(children) && children.length)) {
33
- return <>{variants} {` | ${children}`}</>;
32
+ return (
33
+ <>
34
+ {variants} {` | ${children}`}
35
+ </>
36
+ );
34
37
  }
35
38
 
36
39
  return variants;